@ohtaman/washi 0.5.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 +55 -20
- package/README.md +55 -20
- package/README.zh-CN.md +55 -20
- 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 +1 -1
- package/dist/browser/highs.wasm +0 -0
- package/dist/browser/highs.wasm.LICENSE +1 -2
- package/dist/browser/loader-DewlSho8.js +643 -0
- package/dist/browser/solvers/glpk.js +1 -1
- package/dist/browser/solvers/glpk.min.js +1 -1
- package/dist/browser/solvers/z3.js +7 -1
- package/dist/browser/solvers/z3.min.js +1 -1
- package/dist/browser/washi.js +1096 -444
- package/dist/browser/washi.min.js +3 -4
- package/dist/lib/_washi-node-only-BvRk9kiK.js +0 -0
- package/dist/lib/highs-browser-runtime.js +2120 -4124
- package/dist/lib/highs-node-runtime.js +24 -1
- package/dist/lib/highs-runtime.js +2 -0
- package/dist/lib/highs-worker.js +1 -1
- package/dist/lib/highs.wasm +0 -0
- package/dist/lib/highs.wasm.LICENSE +1 -2
- package/dist/lib/loader-BZUQNvh4.js +649 -0
- package/dist/lib/{registry-BEfvpZW3.js → registry-C20sxTwm.js} +54 -41
- package/dist/lib/solvers/glpk.js +2 -2
- package/dist/lib/solvers/z3.js +1 -1
- package/dist/lib/washi.js +973 -305
- package/dist/types/decomposition/benders.d.ts +32 -0
- package/dist/types/decomposition/benders.d.ts.map +1 -0
- package/dist/types/decomposition/column-generation.d.ts +34 -0
- package/dist/types/decomposition/column-generation.d.ts.map +1 -0
- package/dist/types/decomposition/index.d.ts +4 -0
- package/dist/types/decomposition/index.d.ts.map +1 -0
- package/dist/types/decomposition/types.d.ts +230 -0
- package/dist/types/decomposition/types.d.ts.map +1 -0
- package/dist/types/index.d.ts +4 -3
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/modeler/boolean-expr.d.ts.map +1 -1
- package/dist/types/modeler/constraint.d.ts +11 -0
- package/dist/types/modeler/constraint.d.ts.map +1 -1
- package/dist/types/modeler/expression.d.ts +10 -0
- package/dist/types/modeler/expression.d.ts.map +1 -1
- package/dist/types/modeler/index.d.ts +2 -1
- package/dist/types/modeler/index.d.ts.map +1 -1
- package/dist/types/modeler/linearizer.d.ts +15 -0
- package/dist/types/modeler/linearizer.d.ts.map +1 -0
- package/dist/types/modeler/lp-writer.d.ts +3 -1
- package/dist/types/modeler/lp-writer.d.ts.map +1 -1
- package/dist/types/modeler/model.d.ts +147 -2
- package/dist/types/modeler/model.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/browser-runtime.d.ts +2 -1
- package/dist/types/modeler/solvers/highs/browser-runtime.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/driver.d.ts +232 -0
- package/dist/types/modeler/solvers/highs/driver.d.ts.map +1 -0
- package/dist/types/modeler/solvers/highs/index.d.ts +1 -0
- package/dist/types/modeler/solvers/highs/index.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/loader.d.ts +4 -4
- package/dist/types/modeler/solvers/highs/loader.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/node-runtime.d.ts +2 -1
- package/dist/types/modeler/solvers/highs/node-runtime.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/solver.d.ts +1 -1
- package/dist/types/modeler/solvers/highs/solver.d.ts.map +1 -1
- package/dist/types/modeler/solvers/types.d.ts +2 -0
- package/dist/types/modeler/solvers/types.d.ts.map +1 -1
- package/dist/types/modeler/types.d.ts +27 -0
- package/dist/types/modeler/types.d.ts.map +1 -1
- package/docs/examples/index.md +4 -0
- package/docs/examples/traveling-salesperson.md +173 -0
- package/docs/examples/vehicle-routing.md +206 -0
- package/docs/getting-started/ai-agents.md +8 -4
- package/docs/guide/constraints.md +1 -1
- package/docs/guide/decomposition.md +399 -0
- package/docs/guide/unsat-core.md +10 -3
- package/docs/ja/getting-started/ai-agents.md +8 -4
- package/docs/solvers/custom-solver.md +1 -1
- package/docs/solvers/highs.md +25 -3
- package/docs/solvers/index.md +3 -3
- package/docs/zh/getting-started/ai-agents.md +8 -4
- package/llms-full.txt +831 -15
- package/llms.txt +9 -5
- package/package.json +17 -14
- package/skills/washi/SKILL.md +8 -8
- package/dist/browser/browser-runtime-D13gHOT5.js +0 -4189
- package/dist/browser/loader-CtaDHef_.js +0 -273
- package/dist/lib/loader-DmNC_UNk.js +0 -279
package/dist/browser/washi.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { a as e, i as t, n, o as r, r as i,
|
|
1
|
+
import { a as e, i as t, n, o as r, r as i, s as a, t as o } from "./loader-DewlSho8.js";
|
|
2
2
|
//#region src/modeler/types.ts
|
|
3
|
-
function
|
|
3
|
+
function s(e) {
|
|
4
4
|
if (e === void 0) return "Minimize";
|
|
5
5
|
if (typeof e == "string") {
|
|
6
6
|
let t = e.toLowerCase();
|
|
@@ -11,68 +11,68 @@ function o(e) {
|
|
|
11
11
|
}
|
|
12
12
|
//#endregion
|
|
13
13
|
//#region src/modeler/boolean-expr.ts
|
|
14
|
-
var
|
|
15
|
-
function
|
|
16
|
-
if (e instanceof
|
|
17
|
-
throw typeof e == "object" && e && ("terms" in e || "quadTerms" in e) ? Error(`Cannot use an arithmetic expression without a comparison operator (<=, >=, ==) in logical operator "${t}". Use a comparison constraint such as expr\`\${x} <= 10\` or a BoolVar/BoolExpr.`) : Error(`Invalid operand passed to logical operator "${t}": expected a BoolVar, BoolExpr, or Constraint.`);
|
|
14
|
+
var c = 0;
|
|
15
|
+
function l(e, t) {
|
|
16
|
+
if (e instanceof u || e instanceof y) return e;
|
|
17
|
+
throw typeof e == "object" && e && ("terms" in e || "quadTerms" in e) ? Error(`Cannot use an arithmetic expression without a comparison operator (<=, >=, ==) in logical operator "${t}". Use a comparison constraint such as expr\`\${x} <= 10\` or a BoolVar/BoolExpr.`) : typeof e == "object" && e && "id" in e && "name" in e && "lb" in e && "ub" in e && !("sense" in e) ? Error(`Invalid operand passed to logical operator "${t}": expected a BoolVar, BoolExpr, or Constraint, but received numeric variable "${e.name}". Use m.bool() for propositional variables, add a comparison such as expr\`\${x} == 1\`, or use m.indicator(binVar, constraint) for 0-1 Big-M indicator constraints.`) : Error(`Invalid operand passed to logical operator "${t}": expected a BoolVar, BoolExpr, or Constraint.`);
|
|
18
18
|
}
|
|
19
|
-
var
|
|
19
|
+
var u = class {
|
|
20
20
|
and(e) {
|
|
21
|
-
return new
|
|
21
|
+
return new f("and", [this, l(e, "and")]);
|
|
22
22
|
}
|
|
23
23
|
or(e) {
|
|
24
|
-
return new
|
|
24
|
+
return new f("or", [this, l(e, "or")]);
|
|
25
25
|
}
|
|
26
26
|
implies(e) {
|
|
27
|
-
return new
|
|
27
|
+
return new f("implies", [this, l(e, "implies")]);
|
|
28
28
|
}
|
|
29
29
|
xor(e) {
|
|
30
|
-
return new
|
|
30
|
+
return new f("xor", [this, l(e, "xor")]);
|
|
31
31
|
}
|
|
32
32
|
not() {
|
|
33
|
-
return new
|
|
33
|
+
return new f("not", [this]);
|
|
34
34
|
}
|
|
35
|
-
},
|
|
35
|
+
}, d = class extends u {
|
|
36
36
|
id;
|
|
37
37
|
name;
|
|
38
38
|
value = null;
|
|
39
39
|
constructor(e) {
|
|
40
|
-
super(), this.id = ++
|
|
40
|
+
super(), this.id = ++c, this.name = e || `p_${this.id}`;
|
|
41
41
|
}
|
|
42
42
|
toString() {
|
|
43
43
|
return this.name;
|
|
44
44
|
}
|
|
45
|
-
},
|
|
45
|
+
}, f = class extends u {
|
|
46
46
|
op;
|
|
47
47
|
children;
|
|
48
48
|
constructor(e, t) {
|
|
49
|
-
super(), this.op = e, this.children = t.map((t) =>
|
|
49
|
+
super(), this.op = e, this.children = t.map((t) => l(t, e));
|
|
50
50
|
}
|
|
51
51
|
toString() {
|
|
52
52
|
return this.op === "not" ? `not(${this.children[0].toString()})` : `(${this.children.map((e) => e.toString()).join(` ${this.op} `)})`;
|
|
53
53
|
}
|
|
54
54
|
};
|
|
55
|
-
function
|
|
55
|
+
function p(...e) {
|
|
56
56
|
if (e.length === 0) throw Error("and() requires at least one expression");
|
|
57
|
-
return new
|
|
57
|
+
return new f("and", e);
|
|
58
58
|
}
|
|
59
|
-
function
|
|
59
|
+
function m(...e) {
|
|
60
60
|
if (e.length === 0) throw Error("or() requires at least one expression");
|
|
61
|
-
return new
|
|
61
|
+
return new f("or", e);
|
|
62
62
|
}
|
|
63
|
-
function
|
|
64
|
-
return new
|
|
63
|
+
function h(e) {
|
|
64
|
+
return new f("not", [e]);
|
|
65
65
|
}
|
|
66
|
-
function
|
|
67
|
-
return new
|
|
66
|
+
function g(e, t) {
|
|
67
|
+
return new f("implies", [e, t]);
|
|
68
68
|
}
|
|
69
|
-
function
|
|
69
|
+
function _(...e) {
|
|
70
70
|
if (e.length === 0) throw Error("xor() requires at least one expression");
|
|
71
|
-
return new
|
|
71
|
+
return new f("xor", e);
|
|
72
72
|
}
|
|
73
73
|
//#endregion
|
|
74
74
|
//#region src/modeler/constraint.ts
|
|
75
|
-
var
|
|
75
|
+
var v = 0, y = class e {
|
|
76
76
|
kind = "constraint";
|
|
77
77
|
id;
|
|
78
78
|
_lhs;
|
|
@@ -83,8 +83,14 @@ var _ = 0, v = class e {
|
|
|
83
83
|
ownerModel = null;
|
|
84
84
|
slack = null;
|
|
85
85
|
dual = null;
|
|
86
|
+
addTerm(e, t) {
|
|
87
|
+
return t === 0 ? this : (this._lhs.addTerm(e, t), this.ownerModel?.notifyMutation?.(), this);
|
|
88
|
+
}
|
|
89
|
+
setTerm(e, t) {
|
|
90
|
+
return this._lhs.setTerm(e, t), this.ownerModel?.notifyMutation?.(), this;
|
|
91
|
+
}
|
|
86
92
|
constructor(e, t, n, r) {
|
|
87
|
-
this.id = ++
|
|
93
|
+
this.id = ++v, this._lhs = e, this._sense = t, this._rhs = n;
|
|
88
94
|
let i = typeof r == "string" ? r.trim() : void 0;
|
|
89
95
|
i && i.length > 0 ? (this._name = i, this.hasExplicitName = !0) : (this._name = `c_${this.id}`, this.hasExplicitName = !1);
|
|
90
96
|
}
|
|
@@ -116,19 +122,19 @@ var _ = 0, v = class e {
|
|
|
116
122
|
this._name = e, this.hasExplicitName = t;
|
|
117
123
|
}
|
|
118
124
|
and(e) {
|
|
119
|
-
return new
|
|
125
|
+
return new f("and", [this, e]);
|
|
120
126
|
}
|
|
121
127
|
or(e) {
|
|
122
|
-
return new
|
|
128
|
+
return new f("or", [this, e]);
|
|
123
129
|
}
|
|
124
130
|
implies(e) {
|
|
125
|
-
return new
|
|
131
|
+
return new f("implies", [this, e]);
|
|
126
132
|
}
|
|
127
133
|
xor(e) {
|
|
128
|
-
return new
|
|
134
|
+
return new f("xor", [this, e]);
|
|
129
135
|
}
|
|
130
136
|
not() {
|
|
131
|
-
return new
|
|
137
|
+
return new f("not", [this]);
|
|
132
138
|
}
|
|
133
139
|
add(e) {
|
|
134
140
|
throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
@@ -168,16 +174,16 @@ var _ = 0, v = class e {
|
|
|
168
174
|
return `${this.name}: ${this.lhs.toString()} ${e} ${this.rhs}`;
|
|
169
175
|
}
|
|
170
176
|
};
|
|
171
|
-
function
|
|
172
|
-
return e instanceof
|
|
177
|
+
function b(e) {
|
|
178
|
+
return e instanceof y || typeof e == "object" && !!e && "sense" in e && "lhs" in e && "rhs" in e;
|
|
173
179
|
}
|
|
174
180
|
//#endregion
|
|
175
181
|
//#region src/modeler/quad-expr.ts
|
|
176
|
-
function
|
|
182
|
+
function x(e, t) {
|
|
177
183
|
let n = e.id, r = t.id;
|
|
178
184
|
return n <= r ? `${n}:${r}` : `${r}:${n}`;
|
|
179
185
|
}
|
|
180
|
-
var
|
|
186
|
+
var S = class e {
|
|
181
187
|
kind = "quadratic";
|
|
182
188
|
linearTerms;
|
|
183
189
|
quadTerms;
|
|
@@ -191,11 +197,11 @@ var x = class e {
|
|
|
191
197
|
return new e(this.linearTerms, this.quadTerms, this.constant);
|
|
192
198
|
}
|
|
193
199
|
getQuadCoeff(e, t) {
|
|
194
|
-
let n =
|
|
200
|
+
let n = x(e, t), r = this.quadTerms.get(n);
|
|
195
201
|
return r ? r.coeff : 0;
|
|
196
202
|
}
|
|
197
203
|
add(t) {
|
|
198
|
-
if (
|
|
204
|
+
if (b(t)) throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
199
205
|
let n = this.clone();
|
|
200
206
|
if (typeof t == "number") return n.constant += t, n;
|
|
201
207
|
if (t instanceof e) {
|
|
@@ -224,11 +230,11 @@ var x = class e {
|
|
|
224
230
|
return i === 0 ? n.linearTerms.delete(r) : n.linearTerms.set(r, i), n;
|
|
225
231
|
}
|
|
226
232
|
sub(e) {
|
|
227
|
-
if (
|
|
233
|
+
if (b(e)) throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
228
234
|
return typeof e == "number" ? this.add(-e) : this.add(e.mul(-1));
|
|
229
235
|
}
|
|
230
236
|
mul(t) {
|
|
231
|
-
if (
|
|
237
|
+
if (b(t)) throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
232
238
|
if (typeof t == "number") {
|
|
233
239
|
let n = this.linearTerms.size > 0 || this.quadTerms.size > 0, r = this.constant === 0 && n ? 0 : this.constant * t;
|
|
234
240
|
if (this.constant !== 0 && t !== 0 && r === 0) throw Error("Constant multiplication underflows to zero.");
|
|
@@ -288,7 +294,7 @@ var x = class e {
|
|
|
288
294
|
}
|
|
289
295
|
toConstraint(e, t, n) {
|
|
290
296
|
if (this.quadTerms.size > 0) throw Error(`Quadratic expressions are not supported in linear constraints (${e}): quadratic terms are only allowed in objectives.`);
|
|
291
|
-
let r = new
|
|
297
|
+
let r = new C(this.linearTerms, this.constant);
|
|
292
298
|
return e === "<=" ? r.le(t, n) : e === ">=" ? r.ge(t, n) : r.eq(t, n);
|
|
293
299
|
}
|
|
294
300
|
and(e) {
|
|
@@ -325,7 +331,7 @@ var x = class e {
|
|
|
325
331
|
static fromProduct(t, n, r = 1) {
|
|
326
332
|
let i = new e();
|
|
327
333
|
if (r === 0) return i;
|
|
328
|
-
let a =
|
|
334
|
+
let a = x(t, n);
|
|
329
335
|
return i.quadTerms.set(a, {
|
|
330
336
|
var1: t.id <= n.id ? t : n,
|
|
331
337
|
var2: t.id <= n.id ? n : t,
|
|
@@ -355,7 +361,7 @@ var x = class e {
|
|
|
355
361
|
return s;
|
|
356
362
|
}
|
|
357
363
|
static extractScalarDivisor(e, t) {
|
|
358
|
-
if (
|
|
364
|
+
if (b(e)) throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
359
365
|
if (typeof e == "number") {
|
|
360
366
|
if (e === 0) throw Error(`Division by zero in ${t}`);
|
|
361
367
|
return e;
|
|
@@ -365,19 +371,26 @@ var x = class e {
|
|
|
365
371
|
if (e.constant === 0) throw Error(`Division by zero in ${t}`);
|
|
366
372
|
return e.constant;
|
|
367
373
|
}
|
|
368
|
-
},
|
|
374
|
+
}, C = class e {
|
|
369
375
|
kind = "linear";
|
|
370
376
|
terms;
|
|
371
377
|
constant;
|
|
372
378
|
constructor(e = /* @__PURE__ */ new Map(), t = 0) {
|
|
373
379
|
this.terms = new Map(e), this.constant = t;
|
|
374
380
|
}
|
|
381
|
+
setTerm(e, t) {
|
|
382
|
+
return t === 0 ? this.terms.delete(e) : this.terms.set(e, t), this;
|
|
383
|
+
}
|
|
384
|
+
addTerm(e, t) {
|
|
385
|
+
let n = (this.terms.get(e) ?? 0) + t;
|
|
386
|
+
return n === 0 ? this.terms.delete(e) : this.terms.set(e, n), this;
|
|
387
|
+
}
|
|
375
388
|
clone() {
|
|
376
389
|
return new e(this.terms, this.constant);
|
|
377
390
|
}
|
|
378
391
|
add(e) {
|
|
379
|
-
if (
|
|
380
|
-
if (e instanceof
|
|
392
|
+
if (b(e)) throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
393
|
+
if (e instanceof S) return e.add(this);
|
|
381
394
|
let t = this.clone();
|
|
382
395
|
if (typeof e == "number") t.constant += e;
|
|
383
396
|
else if ("terms" in e) {
|
|
@@ -393,11 +406,11 @@ var x = class e {
|
|
|
393
406
|
return t;
|
|
394
407
|
}
|
|
395
408
|
sub(e) {
|
|
396
|
-
if (
|
|
397
|
-
return e instanceof
|
|
409
|
+
if (b(e)) throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
410
|
+
return e instanceof S ? e.neg().add(this) : typeof e == "number" ? this.add(-e) : this.add(e.mul(-1));
|
|
398
411
|
}
|
|
399
412
|
mul(t) {
|
|
400
|
-
if (
|
|
413
|
+
if (b(t)) throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
401
414
|
if (typeof t == "number") {
|
|
402
415
|
let n = this.constant === 0 && this.terms.size > 0 ? 0 : this.constant * t;
|
|
403
416
|
if (this.constant !== 0 && t !== 0 && n === 0) throw Error("Constant multiplication underflows to zero.");
|
|
@@ -409,10 +422,10 @@ var x = class e {
|
|
|
409
422
|
}
|
|
410
423
|
return r;
|
|
411
424
|
}
|
|
412
|
-
return t instanceof
|
|
425
|
+
return t instanceof M || typeof t == "object" && t && "id" in t && !("terms" in t) && !("quadTerms" in t) ? S.multiplyLinearTerms(this.constant, this.terms, 0, /* @__PURE__ */ new Map([[t, 1]])) : t instanceof S ? this.terms.size === 0 ? t.mul(this.constant) : new S(this.terms, /* @__PURE__ */ new Map(), this.constant).mul(t) : this.terms.size === 0 ? t.mul(this.constant) : t.terms.size === 0 ? this.mul(t.constant) : S.multiplyLinearTerms(this.constant, this.terms, t.constant, t.terms);
|
|
413
426
|
}
|
|
414
427
|
div(e) {
|
|
415
|
-
let t =
|
|
428
|
+
let t = S.extractScalarDivisor(e, "LinExpr.div()");
|
|
416
429
|
return this.mul(1 / t);
|
|
417
430
|
}
|
|
418
431
|
neg() {
|
|
@@ -438,14 +451,14 @@ var x = class e {
|
|
|
438
451
|
toConstraint(t, n, r) {
|
|
439
452
|
let i = this.clone(), a = 0;
|
|
440
453
|
if (typeof n == "number") a = n;
|
|
441
|
-
else if (n instanceof
|
|
442
|
-
else if (n instanceof
|
|
454
|
+
else if (n instanceof y || typeof n == "object" && n && "sense" in n && "lhs" in n) throw Error(`Cannot compare against a Constraint in (${t}): expected a number, Var, or LinExpr.`);
|
|
455
|
+
else if (n instanceof S || typeof n == "object" && n && "quadTerms" in n) {
|
|
443
456
|
let r = n;
|
|
444
457
|
if (r.quadTerms.size > 0) throw Error(`Quadratic expressions are not supported in linear constraints (${t}): quadratic terms are only allowed in objectives.`);
|
|
445
458
|
i = i.sub(new e(r.linearTerms, 0)), a = r.constant;
|
|
446
459
|
} else "terms" in n ? (i = i.sub(new e(n.terms, 0)), a = n.constant) : i = i.sub(n);
|
|
447
460
|
let o = a - i.constant;
|
|
448
|
-
return i.constant = 0, new
|
|
461
|
+
return i.constant = 0, new y(i, t, o, r);
|
|
449
462
|
}
|
|
450
463
|
and(e) {
|
|
451
464
|
throw Error("Cannot use an arithmetic expression without a comparison operator (<=, >=, ==) in logical 'and': expected a BoolVar, Constraint, or BoolOp.");
|
|
@@ -475,13 +488,13 @@ var x = class e {
|
|
|
475
488
|
return e.join(" ") || "0";
|
|
476
489
|
}
|
|
477
490
|
};
|
|
478
|
-
function
|
|
491
|
+
function w(e, t) {
|
|
479
492
|
let n = /* @__PURE__ */ new Map(), r = 0;
|
|
480
493
|
function i(e) {
|
|
481
494
|
if (e != null) {
|
|
482
495
|
if (typeof e == "number") r += e;
|
|
483
|
-
else if (e instanceof
|
|
484
|
-
else if (e instanceof
|
|
496
|
+
else if (e instanceof y || typeof e == "object" && "sense" in e && "lhs" in e && "rhs" in e) throw Error("Cannot sum a constraint comparison (<=, >=, ==) in sum(): expected a number, Var, or LinExpr.");
|
|
497
|
+
else if (e instanceof S || typeof e == "object" && "quadTerms" in e && e.quadTerms instanceof Map) {
|
|
485
498
|
let t = e;
|
|
486
499
|
if (t.quadTerms.size > 0) throw Error("Quadratic expressions are not supported in sum(): sum() produces a linear expression (LinExpr).");
|
|
487
500
|
for (let [e, r] of t.linearTerms) {
|
|
@@ -510,20 +523,20 @@ function C(e, t) {
|
|
|
510
523
|
for (let r of e) i(t ? t(r, n++) : r);
|
|
511
524
|
}
|
|
512
525
|
for (let [e, t] of n) t === 0 && n.delete(e);
|
|
513
|
-
return new
|
|
526
|
+
return new C(n, r);
|
|
514
527
|
}
|
|
515
|
-
function
|
|
528
|
+
function T(e, t) {
|
|
516
529
|
let n = /* @__PURE__ */ new Map(), r = 0;
|
|
517
530
|
function i(e) {
|
|
518
|
-
return typeof e == "object" && !!e && !(e instanceof
|
|
531
|
+
return typeof e == "object" && !!e && !(e instanceof y) && typeof e.id == "number" && typeof e.name == "string" && typeof e.lb == "number" && typeof e.ub == "number" && typeof e.type == "string" && typeof e.mul == "function" && typeof e.le == "function";
|
|
519
532
|
}
|
|
520
533
|
function a(e) {
|
|
521
|
-
return i(e) || e instanceof
|
|
534
|
+
return i(e) || e instanceof C || e instanceof S;
|
|
522
535
|
}
|
|
523
536
|
function o(e, t, a) {
|
|
524
537
|
if (!Number.isFinite(e)) throw Error(`Invalid non-finite coefficient "${e}" in dot() at '${a || "root"}'.`);
|
|
525
|
-
if (t instanceof
|
|
526
|
-
if (t instanceof
|
|
538
|
+
if (t instanceof S) throw Error(`Quadratic expressions are not supported in dot() at '${a || "root"}': dot() produces a linear expression (LinExpr).`);
|
|
539
|
+
if (t instanceof C) {
|
|
527
540
|
if (!Number.isFinite(t.constant)) throw Error(`Invalid non-finite constant "${t.constant}" in dot() at '${a || "root"}'.`);
|
|
528
541
|
let i = e === 0 || t.constant === 0 ? 0 : e * t.constant;
|
|
529
542
|
if (e !== 0 && t.constant !== 0 && i === 0) throw Error("Constant multiplication underflows to zero.");
|
|
@@ -547,7 +560,7 @@ function w(e, t) {
|
|
|
547
560
|
} else throw Error(`Cannot multiply number by non-variable/expression operand in dot() at '${a || "root"}'.`);
|
|
548
561
|
}
|
|
549
562
|
function s(e) {
|
|
550
|
-
return typeof e == "object" && !!e && !Array.isArray(e) && !a(e) && !(e instanceof
|
|
563
|
+
return typeof e == "object" && !!e && !Array.isArray(e) && !a(e) && !(e instanceof y) && e.kind !== "constraint";
|
|
551
564
|
}
|
|
552
565
|
function c(e, t, n = "") {
|
|
553
566
|
if (e === void 0 || t === void 0 || e === null || t === null) throw Error(`Nullish or undefined operand encountered in dot() at '${n || "root"}'.`);
|
|
@@ -595,39 +608,39 @@ function w(e, t) {
|
|
|
595
608
|
}
|
|
596
609
|
c(e, t);
|
|
597
610
|
for (let [e, t] of n) t === 0 && n.delete(e);
|
|
598
|
-
return new
|
|
611
|
+
return new C(n, r);
|
|
599
612
|
}
|
|
600
613
|
//#endregion
|
|
601
614
|
//#region src/modeler/validation.ts
|
|
602
|
-
var
|
|
603
|
-
function
|
|
604
|
-
if (e instanceof
|
|
605
|
-
else if (e instanceof
|
|
606
|
-
let r = e.ownerModel, i =
|
|
615
|
+
var E = /* @__PURE__ */ new WeakMap(), D = /* @__PURE__ */ new WeakMap(), O = /* @__PURE__ */ new WeakMap();
|
|
616
|
+
function k(e, t, n) {
|
|
617
|
+
if (e instanceof f) for (let r of e.children) k(r, t, n);
|
|
618
|
+
else if (e instanceof y) {
|
|
619
|
+
let r = e.ownerModel, i = D.get(e);
|
|
607
620
|
(r !== t || i !== t) && (n && n.push(() => {
|
|
608
|
-
e.ownerModel = r, i ?
|
|
609
|
-
}), e.ownerModel = t,
|
|
621
|
+
e.ownerModel = r, i ? D.set(e, i) : D.delete(e);
|
|
622
|
+
}), e.ownerModel = t, D.set(e, t));
|
|
610
623
|
}
|
|
611
624
|
}
|
|
612
|
-
function
|
|
613
|
-
let n =
|
|
625
|
+
function ee(e, t) {
|
|
626
|
+
let n = E.get(e);
|
|
614
627
|
if (n && n !== t) throw Error(`Variable "${e.name}" already belongs to model "${n.name}" and cannot be added to model "${t.name}".`);
|
|
615
|
-
|
|
628
|
+
E.set(e, t);
|
|
616
629
|
}
|
|
617
|
-
function
|
|
618
|
-
let n =
|
|
630
|
+
function te(e, t) {
|
|
631
|
+
let n = O.get(e);
|
|
619
632
|
if (n) throw Error(n === t ? `Constraint "${e.name}" is already registered in model "${t.name}".` : `Constraint "${e.name}" already belongs to model "${n.name}" and cannot be added to model "${t.name}".`);
|
|
620
|
-
let r =
|
|
633
|
+
let r = D.get(e);
|
|
621
634
|
if (r && r !== t) throw Error(`Constraint "${e.name}" already belongs to model "${r.name}" and cannot be added to model "${t.name}".`);
|
|
622
|
-
return
|
|
635
|
+
return O.set(e, t), D.set(e, t), r;
|
|
623
636
|
}
|
|
624
|
-
function
|
|
625
|
-
|
|
637
|
+
function ne(e, t) {
|
|
638
|
+
E.get(e) === t && E.delete(e);
|
|
626
639
|
}
|
|
627
|
-
function
|
|
628
|
-
|
|
640
|
+
function re(e, t, n) {
|
|
641
|
+
O.get(e) === t && O.delete(e), D.get(e) === t && (n ? D.set(e, n) : D.delete(e));
|
|
629
642
|
}
|
|
630
|
-
var
|
|
643
|
+
var ie = 1e-6;
|
|
631
644
|
function A(e) {
|
|
632
645
|
if (typeof e.lb != "number" || Number.isNaN(e.lb)) throw Error(`Variable "${e.name}" has invalid lower bound: ${e.lb} (NaN or non-numeric bound is not allowed).`);
|
|
633
646
|
if (e.lb === Infinity) throw Error(`Variable "${e.name}" has invalid lower bound: +Infinity is not allowed as a lower bound.`);
|
|
@@ -637,14 +650,14 @@ function A(e) {
|
|
|
637
650
|
if (e.initialValue !== void 0) {
|
|
638
651
|
if (typeof e.initialValue != "number" || !Number.isFinite(e.initialValue)) throw Error(`Variable "${e.name}" has invalid initialValue: ${String(e.initialValue)} (initialValue must be a finite number).`);
|
|
639
652
|
let t = e.type === "Binary" ? Math.max(0, e.lb) : e.lb, n = e.type === "Binary" ? Math.min(1, e.ub) : e.ub;
|
|
640
|
-
if (e.initialValue < t - 1e-6 || e.initialValue > n + 1e-6) throw Error(`Variable "${e.name}" has initialValue (${e.initialValue}) outside its bounds [${t}, ${n}] (tolerance ${
|
|
653
|
+
if (e.initialValue < t - 1e-6 || e.initialValue > n + 1e-6) throw Error(`Variable "${e.name}" has initialValue (${e.initialValue}) outside its bounds [${t}, ${n}] (tolerance ${ie}).`);
|
|
641
654
|
if (e.type === "Integer" || e.type === "Binary") {
|
|
642
655
|
let r = Math.round(e.initialValue);
|
|
643
|
-
if (Math.abs(e.initialValue - r) > 1e-6 || r < t || r > n) throw Error(`Variable "${e.name}" of type "${e.type}" has non-integral or out-of-domain initialValue: ${e.initialValue} (must be within ${
|
|
656
|
+
if (Math.abs(e.initialValue - r) > 1e-6 || r < t || r > n) throw Error(`Variable "${e.name}" of type "${e.type}" has non-integral or out-of-domain initialValue: ${e.initialValue} (must be within ${ie} of an integer in [${t}, ${n}]).`);
|
|
644
657
|
}
|
|
645
658
|
}
|
|
646
659
|
}
|
|
647
|
-
function
|
|
660
|
+
function ae(e) {
|
|
648
661
|
if (e.initialValue === void 0) return;
|
|
649
662
|
if (A(e), e.type === "Integer" || e.type === "Binary") {
|
|
650
663
|
let t = Math.round(e.initialValue);
|
|
@@ -653,8 +666,8 @@ function ie(e) {
|
|
|
653
666
|
let t = Math.min(e.ub, Math.max(e.lb, e.initialValue));
|
|
654
667
|
return Object.is(t, -0) ? 0 : t;
|
|
655
668
|
}
|
|
656
|
-
function
|
|
657
|
-
if (e instanceof
|
|
669
|
+
function oe(e, t, n) {
|
|
670
|
+
if (e instanceof S) {
|
|
658
671
|
if (!Number.isFinite(e.constant)) throw Error(`Objective function has invalid constant: ${e.constant}. Constant must be a finite number.`);
|
|
659
672
|
for (let [r, i] of e.linearTerms) {
|
|
660
673
|
if (!n(r)) throw Error(`Variable "${r.name}" in objective function does not belong to model "${t}". All variables must belong to the model by object identity.`);
|
|
@@ -681,13 +694,13 @@ function j(e, t, n, r = e.name) {
|
|
|
681
694
|
if (!Number.isFinite(a)) throw Error(`Variable "${i.name}" in constraint "${r}" has invalid coefficient: ${a}. Coefficients must be finite numbers.`);
|
|
682
695
|
}
|
|
683
696
|
}
|
|
684
|
-
function
|
|
685
|
-
if (e instanceof
|
|
697
|
+
function se(e, t, n, r, i, a) {
|
|
698
|
+
if (e instanceof d) {
|
|
686
699
|
if (!i(e)) throw Error(`Boolean variable "${e.name}" in logical constraint "${t}" does not belong to model "${n}".`);
|
|
687
|
-
} else if (e instanceof
|
|
688
|
-
else if (e instanceof
|
|
700
|
+
} else if (e instanceof f) for (let o of e.children) se(o, t, n, r, i, a);
|
|
701
|
+
else if (e instanceof y) {
|
|
689
702
|
if (a) {
|
|
690
|
-
let r =
|
|
703
|
+
let r = D.get(e) ?? e.ownerModel ?? void 0;
|
|
691
704
|
if (r && r !== a) throw Error(`Constraint "${e.name}" embedded in logical constraint "${t}" already belongs to model "${r.name ?? "another model"}" and cannot be added to model "${n}".`);
|
|
692
705
|
}
|
|
693
706
|
if (!Number.isFinite(e.rhs)) throw Error(`Constraint "${e.name}" embedded in logical constraint "${t}" has invalid RHS: ${e.rhs}.`);
|
|
@@ -698,11 +711,11 @@ function M(e, t, n, r, i, a) {
|
|
|
698
711
|
}
|
|
699
712
|
}
|
|
700
713
|
}
|
|
701
|
-
function
|
|
714
|
+
function ce(e) {
|
|
702
715
|
let t = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new Set();
|
|
703
716
|
for (let r of e.variables) {
|
|
704
717
|
A(r);
|
|
705
|
-
let i =
|
|
718
|
+
let i = E.get(r);
|
|
706
719
|
if (i && i !== e || t.has(r.name) || e.getVarByName(r.name) !== r) throw Error(`Variable "${r.name}" is duplicated or not canonically registered in model "${e.name}".`);
|
|
707
720
|
t.add(r.name), n.add(r);
|
|
708
721
|
}
|
|
@@ -723,18 +736,18 @@ function oe(e) {
|
|
|
723
736
|
a.add(t.name);
|
|
724
737
|
}
|
|
725
738
|
for (let t of e.constraints) {
|
|
726
|
-
let n =
|
|
739
|
+
let n = D.get(t);
|
|
727
740
|
if (n && n !== e || e.getConstraintByName(t.name) !== t) throw Error(`Constraint "${t.name}" is duplicated or not canonically registered in model "${e.name}".`);
|
|
728
741
|
}
|
|
729
742
|
for (let t of e.logicalConstraints) if (e.getLogicalConstraintByName(t.name) !== t) throw Error(`Logical constraint "${t.name}" is duplicated or not canonically registered in model "${e.name}".`);
|
|
730
|
-
e.objectiveExpr &&
|
|
743
|
+
e.objectiveExpr && oe(e.objectiveExpr, e.name, (e) => n.has(e));
|
|
731
744
|
for (let t of e.constraints) j(t, e.name, (e) => n.has(e));
|
|
732
|
-
for (let t of e.logicalConstraints)
|
|
745
|
+
for (let t of e.logicalConstraints) se(t.expr, t.name, e.name, (e) => n.has(e), (e) => i.has(e), e);
|
|
733
746
|
}
|
|
734
747
|
//#endregion
|
|
735
748
|
//#region src/modeler/variable.ts
|
|
736
|
-
var
|
|
737
|
-
function
|
|
749
|
+
var le = 0;
|
|
750
|
+
function ue(e) {
|
|
738
751
|
if (e === void 0) return "Continuous";
|
|
739
752
|
if (typeof e == "string") {
|
|
740
753
|
let t = e.toLowerCase();
|
|
@@ -744,7 +757,7 @@ function ce(e) {
|
|
|
744
757
|
}
|
|
745
758
|
throw Error(`Invalid variable type "${String(e)}": expected "Continuous", "Integer", or "Binary".`);
|
|
746
759
|
}
|
|
747
|
-
var
|
|
760
|
+
var M = class {
|
|
748
761
|
id;
|
|
749
762
|
_name;
|
|
750
763
|
prefix;
|
|
@@ -757,9 +770,9 @@ var N = class {
|
|
|
757
770
|
value = null;
|
|
758
771
|
reducedCost = null;
|
|
759
772
|
constructor(e = {}) {
|
|
760
|
-
this.id = ++
|
|
773
|
+
this.id = ++le;
|
|
761
774
|
let t = typeof e.name == "string" ? e.name.trim() : "", n = typeof e.prefix == "string" ? e.prefix.trim() : "";
|
|
762
|
-
this.prefix = n.length > 0 ? n : "x", this.hasExplicitName = t.length > 0, this._name = this.hasExplicitName ? t : `${this.prefix}_${this.id}`, this._type =
|
|
775
|
+
this.prefix = n.length > 0 ? n : "x", this.hasExplicitName = t.length > 0, this._name = this.hasExplicitName ? t : `${this.prefix}_${this.id}`, this._type = ue(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), this._initialValue = e.initialValue === void 0 ? void 0 : Object.is(e.initialValue, -0) ? 0 : e.initialValue, this._initialValue !== void 0 && A(this);
|
|
763
776
|
}
|
|
764
777
|
get name() {
|
|
765
778
|
return this._name;
|
|
@@ -768,7 +781,7 @@ var N = class {
|
|
|
768
781
|
return this._type;
|
|
769
782
|
}
|
|
770
783
|
set type(e) {
|
|
771
|
-
let t =
|
|
784
|
+
let t = ue(e);
|
|
772
785
|
this._type !== t && (this._type = t, this.ownerModel?.notifyMutation?.());
|
|
773
786
|
}
|
|
774
787
|
get lb() {
|
|
@@ -794,31 +807,31 @@ var N = class {
|
|
|
794
807
|
this._name = e;
|
|
795
808
|
}
|
|
796
809
|
mul(e) {
|
|
797
|
-
return typeof e == "number" ? new
|
|
810
|
+
return typeof e == "number" ? new C(/* @__PURE__ */ new Map([[this, 1]]), 0).mul(e) : new S(/* @__PURE__ */ new Map([[this, 1]]), /* @__PURE__ */ new Map(), 0).mul(e);
|
|
798
811
|
}
|
|
799
812
|
add(e) {
|
|
800
|
-
return e instanceof
|
|
813
|
+
return e instanceof S ? e.add(this) : new C(/* @__PURE__ */ new Map([[this, 1]]), 0).add(e);
|
|
801
814
|
}
|
|
802
815
|
sub(e) {
|
|
803
|
-
return e instanceof
|
|
816
|
+
return e instanceof S ? e.neg().add(this) : new C(/* @__PURE__ */ new Map([[this, 1]]), 0).sub(e);
|
|
804
817
|
}
|
|
805
818
|
neg() {
|
|
806
819
|
return this.mul(-1);
|
|
807
820
|
}
|
|
808
821
|
le(e, t) {
|
|
809
|
-
return new
|
|
822
|
+
return new C(/* @__PURE__ */ new Map([[this, 1]]), 0).le(e, t);
|
|
810
823
|
}
|
|
811
824
|
ge(e, t) {
|
|
812
|
-
return new
|
|
825
|
+
return new C(/* @__PURE__ */ new Map([[this, 1]]), 0).ge(e, t);
|
|
813
826
|
}
|
|
814
827
|
eq(e, t) {
|
|
815
|
-
return new
|
|
828
|
+
return new C(/* @__PURE__ */ new Map([[this, 1]]), 0).eq(e, t);
|
|
816
829
|
}
|
|
817
830
|
toString() {
|
|
818
831
|
return this.name;
|
|
819
832
|
}
|
|
820
|
-
},
|
|
821
|
-
function
|
|
833
|
+
}, de = /^(?:[0-9]+(?:\.[0-9]+)?|\.[0-9]+)(?:[eE][+-]?[0-9]+)?$/;
|
|
834
|
+
function fe(e, t) {
|
|
822
835
|
let n = [], r = 0, i = e.length;
|
|
823
836
|
for (; r < i;) {
|
|
824
837
|
let a = e[r];
|
|
@@ -874,7 +887,7 @@ function ue(e, t) {
|
|
|
874
887
|
for (; r < i && (e[r] === "." || e[r] === "e" || e[r] === "E" || /[0-9]/.test(e[r]));) a += e[r++];
|
|
875
888
|
}
|
|
876
889
|
} else for (; r < i && (e[r] === "." || /[0-9]/.test(e[r]));) a += e[r++];
|
|
877
|
-
if (!
|
|
890
|
+
if (!de.test(a)) throw Error(`Invalid numeric literal '${a}' at position ${t} in: "${e}"`);
|
|
878
891
|
let o = Number(a);
|
|
879
892
|
if (!Number.isFinite(o)) throw Error(`Numeric literal '${a}' overflows finite floating-point range in: "${e}"`);
|
|
880
893
|
if (o === 0 && !/^[0.]+(?:[eE][+-]?\d+)?$/.test(a)) throw Error(`Numeric literal '${a}' underflows to zero at position ${t} in: "${e}"`);
|
|
@@ -901,7 +914,7 @@ function ue(e, t) {
|
|
|
901
914
|
}
|
|
902
915
|
return n;
|
|
903
916
|
}
|
|
904
|
-
var
|
|
917
|
+
var pe = class {
|
|
905
918
|
tokens;
|
|
906
919
|
pos = 0;
|
|
907
920
|
resolver;
|
|
@@ -926,7 +939,7 @@ var de = class {
|
|
|
926
939
|
else if (t.type === "MINUS") this.consume(), e = e.sub(this.parseTerm());
|
|
927
940
|
else break;
|
|
928
941
|
}
|
|
929
|
-
return e instanceof
|
|
942
|
+
return e instanceof S && e.quadTerms.size === 0 ? new C(e.linearTerms, e.constant) : e;
|
|
930
943
|
}
|
|
931
944
|
parseTerm() {
|
|
932
945
|
let e = this.parseFactor();
|
|
@@ -952,15 +965,15 @@ var de = class {
|
|
|
952
965
|
let e;
|
|
953
966
|
if (this.peek()?.type === "IDENT") {
|
|
954
967
|
let t = this.consume(), n = this.resolve(t.value);
|
|
955
|
-
e = n instanceof
|
|
968
|
+
e = n instanceof M || "id" in n && !("terms" in n) && !("quadTerms" in n) ? new C(/* @__PURE__ */ new Map([[n, 1]]), 0) : n.clone();
|
|
956
969
|
} else this.consume("LPAREN"), e = this.parseExpression(), this.consume("RPAREN");
|
|
957
970
|
return this.applyPower(e).mul(n);
|
|
958
971
|
}
|
|
959
|
-
t = new
|
|
972
|
+
t = new C(/* @__PURE__ */ new Map(), n);
|
|
960
973
|
} else if (e.type === "IDENT") {
|
|
961
974
|
this.consume();
|
|
962
975
|
let n = this.resolve(e.value);
|
|
963
|
-
t = n instanceof
|
|
976
|
+
t = n instanceof M || "id" in n && !("terms" in n) && !("quadTerms" in n) ? new C(/* @__PURE__ */ new Map([[n, 1]]), 0) : n.clone();
|
|
964
977
|
} else if (e.type === "LPAREN") this.consume("LPAREN"), t = this.parseExpression(), this.consume("RPAREN");
|
|
965
978
|
else throw Error(`Unexpected token '${e.value}' in expression`);
|
|
966
979
|
return this.applyPower(t);
|
|
@@ -982,13 +995,13 @@ var de = class {
|
|
|
982
995
|
let n = t[t.length - 1];
|
|
983
996
|
for (let e = t.length - 2; e >= 0; e--) n = t[e] ** +n;
|
|
984
997
|
if (!Number.isFinite(n) || n < 0) throw Error("Exponent creates an invalid or out-of-range power");
|
|
985
|
-
let r = e instanceof
|
|
998
|
+
let r = e instanceof S, i = r ? e.quadTerms.size : 0, a = r ? e.linearTerms.size : e.terms.size;
|
|
986
999
|
if (i === 0 && a === 0) {
|
|
987
1000
|
let t = e.constant ** +n;
|
|
988
1001
|
if (e.constant !== 0 && n > 0 && t === 0) throw Error("Constant exponentiation underflows to zero.");
|
|
989
|
-
return new
|
|
1002
|
+
return new C(/* @__PURE__ */ new Map(), t);
|
|
990
1003
|
}
|
|
991
|
-
if (n === 0) return new
|
|
1004
|
+
if (n === 0) return new C(/* @__PURE__ */ new Map(), 1);
|
|
992
1005
|
if (n === 1) return e;
|
|
993
1006
|
if (n === 2) return e.mul(e);
|
|
994
1007
|
throw Error(`Exponent ${n} creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)`);
|
|
@@ -1002,15 +1015,15 @@ var de = class {
|
|
|
1002
1015
|
return t;
|
|
1003
1016
|
}
|
|
1004
1017
|
};
|
|
1005
|
-
function
|
|
1006
|
-
let r = new
|
|
1018
|
+
function N(e, t, n) {
|
|
1019
|
+
let r = new pe(fe(e, n), t), i = r.parseExpression(), a = r.getRemainingToken();
|
|
1007
1020
|
if (a) throw Error(`Unexpected token '${a.value}' after expression in "${e}"`);
|
|
1008
|
-
return
|
|
1021
|
+
return P(i), i;
|
|
1009
1022
|
}
|
|
1010
|
-
function
|
|
1011
|
-
return
|
|
1023
|
+
function me(e, t) {
|
|
1024
|
+
return N(e, t);
|
|
1012
1025
|
}
|
|
1013
|
-
function
|
|
1026
|
+
function he(e, t, n, r) {
|
|
1014
1027
|
let i = e.match(/(<=|>=|==|=<|=>|=)/);
|
|
1015
1028
|
if (!i) throw Error(`Constraint must contain a comparison operator (<=, >=, ==, =): "${e}"`);
|
|
1016
1029
|
let a = i[0], o = i.index, s = e.substring(0, o).trim(), c = e.substring(o + a.length).trim(), l;
|
|
@@ -1018,19 +1031,19 @@ function pe(e, t, n, r) {
|
|
|
1018
1031
|
else if (a === ">=" || a === "=>") l = ">=";
|
|
1019
1032
|
else if (a === "==" || a === "=") l = "==";
|
|
1020
1033
|
else throw Error(`Unsupported operator "${a}"`);
|
|
1021
|
-
let u =
|
|
1022
|
-
if (u instanceof
|
|
1023
|
-
let f = u instanceof
|
|
1024
|
-
if (m = l === "<=" ? f.le(p, n) : l === ">=" ? f.ge(p, n) : f.eq(p, n),
|
|
1034
|
+
let u = N(s, t, r), d = N(c, t, r);
|
|
1035
|
+
if (u instanceof S && u.quadTerms.size > 0 || d instanceof S && d.quadTerms.size > 0) throw Error("Quadratic constraints are not supported (only linear constraints are allowed in MILP/LP/QP)");
|
|
1036
|
+
let f = u instanceof S ? new C(u.linearTerms, u.constant) : u, p = d instanceof S ? new C(d.linearTerms, d.constant) : d, m;
|
|
1037
|
+
if (m = l === "<=" ? f.le(p, n) : l === ">=" ? f.ge(p, n) : f.eq(p, n), P(m.lhs), !Number.isFinite(m.rhs)) throw Error(`Invalid non-finite right-hand side "${m.rhs}" in constraint.`);
|
|
1025
1038
|
return m;
|
|
1026
1039
|
}
|
|
1027
|
-
function
|
|
1028
|
-
return
|
|
1040
|
+
function ge(e, t, n) {
|
|
1041
|
+
return he(e, t, n);
|
|
1029
1042
|
}
|
|
1030
|
-
function
|
|
1031
|
-
return e instanceof
|
|
1043
|
+
function _e(e) {
|
|
1044
|
+
return e instanceof M || e instanceof C || e instanceof S ? !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";
|
|
1032
1045
|
}
|
|
1033
|
-
function
|
|
1046
|
+
function P(e) {
|
|
1034
1047
|
if ("constant" in e && !Number.isFinite(e.constant)) throw Error(`Invalid non-finite constant "${e.constant}" in expression.`);
|
|
1035
1048
|
if ("terms" in e && e.terms instanceof Map) {
|
|
1036
1049
|
for (let [, t] of e.terms) if (!Number.isFinite(t)) throw Error(`Invalid non-finite coefficient "${t}" in expression.`);
|
|
@@ -1042,10 +1055,10 @@ function F(e) {
|
|
|
1042
1055
|
for (let [, t] of e.quadTerms) if (!Number.isFinite(t.coeff)) throw Error(`Invalid non-finite quadratic coefficient "${t.coeff}" in expression.`);
|
|
1043
1056
|
}
|
|
1044
1057
|
}
|
|
1045
|
-
function
|
|
1046
|
-
return e instanceof
|
|
1058
|
+
function ve(e) {
|
|
1059
|
+
return e instanceof y || typeof e == "object" && !!e && "sense" in e && "lhs" in e && "rhs" in e;
|
|
1047
1060
|
}
|
|
1048
|
-
function
|
|
1061
|
+
function ye(e, t) {
|
|
1049
1062
|
let n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map(), i = e.join(""), a = "__washi_";
|
|
1050
1063
|
for (; i.includes(a);) a += "_";
|
|
1051
1064
|
let o = "";
|
|
@@ -1055,9 +1068,9 @@ function _e(e, t) {
|
|
|
1055
1068
|
if (!Number.isFinite(e)) throw Error(`Invalid numeric value "${e}" in template expression: interpolated numbers must be finite.`);
|
|
1056
1069
|
let t = `${a}num_${i}__`;
|
|
1057
1070
|
r.set(t, e), o += `(${t})`;
|
|
1058
|
-
} else if (
|
|
1059
|
-
else if (
|
|
1060
|
-
|
|
1071
|
+
} else if (ve(e)) throw Error("Cannot interpolate a constraint comparison (<=, >=, ==) inside a template expression: expected a finite number, Var, LinExpr, or QuadExpr.");
|
|
1072
|
+
else if (_e(e)) {
|
|
1073
|
+
P(e);
|
|
1061
1074
|
let t = `${a}ph_${i}__`;
|
|
1062
1075
|
n.set(t, e), o += ` ${t} `;
|
|
1063
1076
|
} else throw Error("Unsupported interpolation value in template expression: expected a finite number, Var, LinExpr, or QuadExpr.");
|
|
@@ -1068,31 +1081,31 @@ function _e(e, t) {
|
|
|
1068
1081
|
numberMap: r
|
|
1069
1082
|
};
|
|
1070
1083
|
}
|
|
1071
|
-
function
|
|
1072
|
-
let { fullText: n, resolver: r, numberMap: i } =
|
|
1073
|
-
return /(<=|>=|==|=<|=>|=)/.test(n) ?
|
|
1084
|
+
function be(e, ...t) {
|
|
1085
|
+
let { fullText: n, resolver: r, numberMap: i } = ye(e, t);
|
|
1086
|
+
return /(<=|>=|==|=<|=>|=)/.test(n) ? he(n, r, void 0, i) : N(n, r, i);
|
|
1074
1087
|
}
|
|
1075
1088
|
//#endregion
|
|
1076
1089
|
//#region src/modeler/lp-writer.ts
|
|
1077
|
-
function
|
|
1090
|
+
function F(e) {
|
|
1078
1091
|
return typeof e == "object" && !!e && typeof e.lpString == "string" && e.nameToVar instanceof Map && e.nameToConstraint instanceof Map;
|
|
1079
1092
|
}
|
|
1080
|
-
function
|
|
1093
|
+
function I(e, t = "x", n = 0) {
|
|
1081
1094
|
let r = e.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
1082
1095
|
return /^[0-9]/.test(r) && (r = `${t}_${r}`), (!r || r.length === 0) && (r = `${t}_${n}`), r;
|
|
1083
1096
|
}
|
|
1084
|
-
function
|
|
1097
|
+
function xe(e) {
|
|
1085
1098
|
let t = e.variables || [], n = e.constraints || [], r = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Map(), o = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Set();
|
|
1086
1099
|
for (let e = 0; e < t.length; e++) {
|
|
1087
1100
|
let n = t[e];
|
|
1088
1101
|
s.set(n, e);
|
|
1089
|
-
let a =
|
|
1102
|
+
let a = I(n.name, "x", e), o = a, l = 1;
|
|
1090
1103
|
for (; c.has(o);) o = `${a}_${l++}`;
|
|
1091
1104
|
c.add(o), i.set(n, o), r.set(o, n);
|
|
1092
1105
|
}
|
|
1093
1106
|
let l = /* @__PURE__ */ new Set();
|
|
1094
1107
|
for (let e = 0; e < n.length; e++) {
|
|
1095
|
-
let t = n[e], r =
|
|
1108
|
+
let t = n[e], r = I(t.name, "c", e + 1), i = r, s = 1;
|
|
1096
1109
|
for (; l.has(i);) i = `${r}_${s++}`;
|
|
1097
1110
|
l.add(i), o.set(t, i), a.set(i, t);
|
|
1098
1111
|
}
|
|
@@ -1105,18 +1118,18 @@ function ye(e) {
|
|
|
1105
1118
|
varOrder: s
|
|
1106
1119
|
};
|
|
1107
1120
|
}
|
|
1108
|
-
function
|
|
1109
|
-
let { sense:
|
|
1110
|
-
|
|
1111
|
-
let
|
|
1112
|
-
if (
|
|
1121
|
+
function L(e, t) {
|
|
1122
|
+
let { sense: n, objective: r, constraints: i, variables: a } = e, o = t?.relax === !0, { nameToVar: s, varToName: c, nameToConstraint: l, constrToName: u, varOrder: d } = xe(e), f = [];
|
|
1123
|
+
f.push(n && n.toLowerCase() === "maximize" ? "Maximize" : "Minimize");
|
|
1124
|
+
let p = [], m = !0, h = r instanceof S ? r.linearTerms : r.terms;
|
|
1125
|
+
if (h) for (let [e, t] of h) {
|
|
1113
1126
|
if (t === 0) continue;
|
|
1114
|
-
let n =
|
|
1115
|
-
|
|
1127
|
+
let n = c.get(e), r = t >= 0 ? m ? "" : "+ " : "- ", i = Math.abs(t), a = i === 1 ? "" : `${i} `;
|
|
1128
|
+
p.push(`${r}${a}${n}`), m = !1;
|
|
1116
1129
|
}
|
|
1117
|
-
if (
|
|
1118
|
-
let e = [], t = !0,
|
|
1119
|
-
let t =
|
|
1130
|
+
if (r instanceof S && r.quadTerms.size > 0) {
|
|
1131
|
+
let e = [], t = !0, n = Array.from(r.quadTerms.values()).filter((e) => e.coeff !== 0).map((e) => {
|
|
1132
|
+
let t = d.get(e.var1) ?? e.var1.id, n = d.get(e.var2) ?? e.var2.id, [r, i, a, o] = t <= n ? [
|
|
1120
1133
|
e.var1,
|
|
1121
1134
|
e.var2,
|
|
1122
1135
|
t,
|
|
@@ -1135,88 +1148,88 @@ function R(e) {
|
|
|
1135
1148
|
coeff: e.coeff
|
|
1136
1149
|
};
|
|
1137
1150
|
}).sort((e, t) => e.firstIdx - t.firstIdx || e.secondIdx - t.secondIdx);
|
|
1138
|
-
for (let
|
|
1139
|
-
let
|
|
1140
|
-
|
|
1151
|
+
for (let r of n) {
|
|
1152
|
+
let n = 2 * r.coeff, i = n >= 0 ? t ? "" : "+ " : "- ", a = Math.abs(n), o = a === 1 ? "" : `${a} `, s = c.get(r.firstVar), l = c.get(r.secondVar);
|
|
1153
|
+
r.firstVar === r.secondVar ? e.push(`${i}${o}${s} ^ 2`) : e.push(`${i}${o}${s} * ${l}`), t = !1;
|
|
1141
1154
|
}
|
|
1142
1155
|
if (e.length > 0) {
|
|
1143
1156
|
let t = `[ ${e.join(" ")} ] / 2`;
|
|
1144
|
-
|
|
1157
|
+
p.length > 0 ? p.push("+", t) : p.push(t);
|
|
1145
1158
|
}
|
|
1146
1159
|
}
|
|
1147
|
-
let
|
|
1148
|
-
|
|
1149
|
-
for (let e of
|
|
1150
|
-
let t =
|
|
1160
|
+
let g = p.length > 0 ? p.join(" ") : "0";
|
|
1161
|
+
f.push(` obj: ${g}`), f.push("Subject To");
|
|
1162
|
+
for (let e of i) {
|
|
1163
|
+
let t = u.get(e), n = [], r = !0;
|
|
1151
1164
|
for (let [t, i] of e.lhs.terms) {
|
|
1152
1165
|
if (i === 0) continue;
|
|
1153
|
-
let e =
|
|
1154
|
-
n.push(`${a}${
|
|
1166
|
+
let e = c.get(t), a = i >= 0 ? r ? "" : "+ " : "- ", o = Math.abs(i), s = o === 1 ? "" : `${o} `;
|
|
1167
|
+
n.push(`${a}${s}${e}`), r = !1;
|
|
1155
1168
|
}
|
|
1156
1169
|
let i = n.length > 0 ? n.join(" ") : "0", a = e.sense === "==" ? "=" : e.sense;
|
|
1157
|
-
|
|
1158
|
-
}
|
|
1159
|
-
|
|
1160
|
-
let
|
|
1161
|
-
for (let e of
|
|
1162
|
-
let t =
|
|
1163
|
-
if (e.type === "Binary") {
|
|
1164
|
-
|
|
1170
|
+
f.push(` ${t}: ${i} ${a} ${e.rhs}`);
|
|
1171
|
+
}
|
|
1172
|
+
f.push("Bounds");
|
|
1173
|
+
let _ = [], v = [];
|
|
1174
|
+
for (let e of a) {
|
|
1175
|
+
let t = c.get(e);
|
|
1176
|
+
if (!o && e.type === "Binary") {
|
|
1177
|
+
v.push(t);
|
|
1165
1178
|
continue;
|
|
1166
1179
|
}
|
|
1167
|
-
e.type === "Integer" &&
|
|
1180
|
+
!o && e.type === "Integer" && _.push(t);
|
|
1168
1181
|
let n = e.lb === -Infinity, r = e.ub === Infinity;
|
|
1169
|
-
n && r ?
|
|
1182
|
+
n && r ? f.push(` ${t} free`) : n && !r ? f.push(` -infinity <= ${t} <= ${e.ub}`) : !n && r ? (e.lb !== 0 || e.initialValue !== void 0) && f.push(` ${t} >= ${e.lb}`) : f.push(` ${e.lb} <= ${t} <= ${e.ub}`);
|
|
1170
1183
|
}
|
|
1171
|
-
if (
|
|
1172
|
-
|
|
1173
|
-
for (let e = 0; e <
|
|
1184
|
+
if (_.length > 0) {
|
|
1185
|
+
f.push("Generals");
|
|
1186
|
+
for (let e = 0; e < _.length; e += 10) f.push(" " + _.slice(e, e + 10).join(" "));
|
|
1174
1187
|
}
|
|
1175
|
-
if (
|
|
1176
|
-
|
|
1177
|
-
for (let e = 0; e <
|
|
1188
|
+
if (v.length > 0) {
|
|
1189
|
+
f.push("Binary");
|
|
1190
|
+
for (let e = 0; e < v.length; e += 10) f.push(" " + v.slice(e, e + 10).join(" "));
|
|
1178
1191
|
}
|
|
1179
|
-
return
|
|
1180
|
-
lpString:
|
|
1181
|
-
nameToVar:
|
|
1182
|
-
nameToConstraint:
|
|
1192
|
+
return f.push("End"), {
|
|
1193
|
+
lpString: f.join("\n") + "\n",
|
|
1194
|
+
nameToVar: s,
|
|
1195
|
+
nameToConstraint: l
|
|
1183
1196
|
};
|
|
1184
1197
|
}
|
|
1185
1198
|
//#endregion
|
|
1186
1199
|
//#region src/modeler/solvers/registry.ts
|
|
1187
|
-
var
|
|
1188
|
-
z[
|
|
1189
|
-
var B = z[
|
|
1190
|
-
function
|
|
1200
|
+
var R = Symbol.for("washi.solverRegistry"), Se = Symbol.for("washi.defaultSolverFactory"), z = globalThis;
|
|
1201
|
+
z[R] || (z[R] = /* @__PURE__ */ new Map());
|
|
1202
|
+
var B = z[R];
|
|
1203
|
+
function Ce(e, t) {
|
|
1191
1204
|
B.set(e.toLowerCase(), t);
|
|
1192
1205
|
}
|
|
1193
|
-
function
|
|
1206
|
+
function we(e) {
|
|
1194
1207
|
if (typeof e == "string") {
|
|
1195
1208
|
let t = B.get(e.toLowerCase());
|
|
1196
1209
|
if (!t) throw Error(`Solver '${e}' is not registered.`);
|
|
1197
|
-
z[
|
|
1198
|
-
} else z[
|
|
1210
|
+
z[Se] = t;
|
|
1211
|
+
} else z[Se] = typeof e == "function" ? e : () => e;
|
|
1199
1212
|
}
|
|
1200
|
-
function
|
|
1213
|
+
function V(e, t) {
|
|
1201
1214
|
if (!e) {
|
|
1202
|
-
let e = z[
|
|
1203
|
-
if (!e) throw Error(`No default solver available. Available solvers: ${
|
|
1215
|
+
let e = z[Se] || B.get("highs");
|
|
1216
|
+
if (!e) throw Error(`No default solver available. Available solvers: ${H().join(", ")}`);
|
|
1204
1217
|
return e(t);
|
|
1205
1218
|
}
|
|
1206
1219
|
if (typeof e == "string") {
|
|
1207
1220
|
let n = e.toLowerCase(), r = B.get(n);
|
|
1208
|
-
if (!r) throw Error(n === "glpk" ? `Solver 'glpk' not found. Available solvers: ${
|
|
1221
|
+
if (!r) throw Error(n === "glpk" ? `Solver 'glpk' not found. Available solvers: ${H().join(", ")}. Please import '@ohtaman/washi/solvers/glpk' before selecting this solver.` : n === "z3" ? `Solver 'z3' not found. Available solvers: ${H().join(", ")}. Please import '@ohtaman/washi/solvers/z3' before selecting this solver.` : `Solver '${e}' not found. Available solvers: ${H().join(", ")}`);
|
|
1209
1222
|
return r(t);
|
|
1210
1223
|
}
|
|
1211
1224
|
return e;
|
|
1212
1225
|
}
|
|
1213
|
-
function
|
|
1226
|
+
function H() {
|
|
1214
1227
|
return Array.from(B.keys());
|
|
1215
1228
|
}
|
|
1216
1229
|
//#endregion
|
|
1217
1230
|
//#region \0washi-browser-worker-factory
|
|
1218
|
-
function
|
|
1219
|
-
let e =
|
|
1231
|
+
function Te() {
|
|
1232
|
+
let e = a("highs-worker.js");
|
|
1220
1233
|
if (new URL(e).origin === window.location.origin) return new Worker(e, { type: "module" });
|
|
1221
1234
|
let t = URL.createObjectURL(new Blob(["import " + JSON.stringify(e) + ";"], { type: "text/javascript" }));
|
|
1222
1235
|
try {
|
|
@@ -1228,8 +1241,8 @@ function Ce() {
|
|
|
1228
1241
|
}
|
|
1229
1242
|
//#endregion
|
|
1230
1243
|
//#region src/modeler/solvers/highs/worker-client.ts
|
|
1231
|
-
var
|
|
1232
|
-
function
|
|
1244
|
+
var U = null, Ee = 0, W = /* @__PURE__ */ new Map();
|
|
1245
|
+
function De(e, t) {
|
|
1233
1246
|
return e ? {
|
|
1234
1247
|
Status: "Interrupted",
|
|
1235
1248
|
StatusCode: 17,
|
|
@@ -1253,8 +1266,8 @@ function K(e, t) {
|
|
|
1253
1266
|
Rows: []
|
|
1254
1267
|
};
|
|
1255
1268
|
}
|
|
1256
|
-
function
|
|
1257
|
-
let t =
|
|
1269
|
+
function G(e) {
|
|
1270
|
+
let t = W.values().next().value;
|
|
1258
1271
|
if (t && !t.dispatched) {
|
|
1259
1272
|
t.dispatched = !0;
|
|
1260
1273
|
try {
|
|
@@ -1266,30 +1279,30 @@ function q(e) {
|
|
|
1266
1279
|
...t.reportProgress ? { reportProgress: !0 } : {}
|
|
1267
1280
|
});
|
|
1268
1281
|
} catch (n) {
|
|
1269
|
-
|
|
1282
|
+
W.delete(t.id), t.cleanupAbort?.(), t.reject(n), G(e);
|
|
1270
1283
|
}
|
|
1271
1284
|
}
|
|
1272
1285
|
}
|
|
1273
|
-
function
|
|
1274
|
-
let e =
|
|
1275
|
-
e && (
|
|
1276
|
-
for (let e of
|
|
1277
|
-
if (
|
|
1278
|
-
let e =
|
|
1279
|
-
if (e)
|
|
1286
|
+
function Oe() {
|
|
1287
|
+
let e = U;
|
|
1288
|
+
e && (U = null, e.terminate());
|
|
1289
|
+
for (let e of W.values()) e.dispatched = !1;
|
|
1290
|
+
if (W.size > 0) {
|
|
1291
|
+
let e = ke();
|
|
1292
|
+
if (e) G(e);
|
|
1280
1293
|
else {
|
|
1281
1294
|
let e = /* @__PURE__ */ Error("[WaSHI] Failed to recreate HiGHS Worker after interruption.");
|
|
1282
|
-
for (let t of Array.from(
|
|
1295
|
+
for (let t of Array.from(W.values())) W.delete(t.id), t.cleanupAbort?.(), t.reject(e);
|
|
1283
1296
|
}
|
|
1284
1297
|
}
|
|
1285
1298
|
}
|
|
1286
|
-
function
|
|
1299
|
+
function ke() {
|
|
1287
1300
|
if (typeof window > "u" || typeof Worker > "u") return null;
|
|
1288
|
-
if (!
|
|
1289
|
-
|
|
1290
|
-
let e =
|
|
1291
|
-
|
|
1292
|
-
let { type: n, id: r, result: i, runTime: a, error: o, progress: s, incumbent: c } = t.data, l =
|
|
1301
|
+
if (!U) try {
|
|
1302
|
+
U = Te();
|
|
1303
|
+
let e = U;
|
|
1304
|
+
U.onmessage = (t) => {
|
|
1305
|
+
let { type: n, id: r, result: i, runTime: a, error: o, progress: s, incumbent: c } = t.data, l = W.get(r);
|
|
1293
1306
|
if (l) {
|
|
1294
1307
|
if (n === "SOLVE_PROGRESS") {
|
|
1295
1308
|
if (s) {
|
|
@@ -1297,10 +1310,10 @@ function Ee() {
|
|
|
1297
1310
|
try {
|
|
1298
1311
|
l.onProgress?.(s);
|
|
1299
1312
|
} catch (e) {
|
|
1300
|
-
let t =
|
|
1313
|
+
let t = W.get(r);
|
|
1301
1314
|
if (t) {
|
|
1302
|
-
let n =
|
|
1303
|
-
|
|
1315
|
+
let n = W.keys().next().value;
|
|
1316
|
+
W.delete(r), t.cleanupAbort?.(), n === r && Oe(), t.reject(e);
|
|
1304
1317
|
}
|
|
1305
1318
|
}
|
|
1306
1319
|
}
|
|
@@ -1310,41 +1323,41 @@ function Ee() {
|
|
|
1310
1323
|
c && (l.lastIncumbent = c);
|
|
1311
1324
|
return;
|
|
1312
1325
|
}
|
|
1313
|
-
|
|
1326
|
+
W.delete(r), l.cleanupAbort?.(), n === "SOLVE_SUCCESS" ? l.resolve({
|
|
1314
1327
|
result: i,
|
|
1315
1328
|
runTime: a
|
|
1316
|
-
}) : l.reject(Error(o || "Worker solve failed")),
|
|
1329
|
+
}) : l.reject(Error(o || "Worker solve failed")), U === e && G(e);
|
|
1317
1330
|
}
|
|
1318
1331
|
};
|
|
1319
1332
|
let t = (t) => {
|
|
1320
|
-
if (
|
|
1321
|
-
|
|
1322
|
-
for (let e of
|
|
1323
|
-
|
|
1333
|
+
if (U === e) {
|
|
1334
|
+
U = null, e.terminate();
|
|
1335
|
+
for (let e of W.values()) e.cleanupAbort?.(), e.reject(t);
|
|
1336
|
+
W.clear();
|
|
1324
1337
|
}
|
|
1325
1338
|
};
|
|
1326
|
-
|
|
1339
|
+
U.onerror = (e) => t(/* @__PURE__ */ Error(`[WaSHI] HiGHS Worker failed to load or execute. Check Worker assets, CORS and CSP. ${e?.message || ""}`)), U.onmessageerror = () => t(/* @__PURE__ */ Error("[WaSHI] Could not deserialize the HiGHS Worker response."));
|
|
1327
1340
|
} catch {
|
|
1328
|
-
|
|
1341
|
+
U = null;
|
|
1329
1342
|
}
|
|
1330
|
-
return
|
|
1343
|
+
return U;
|
|
1331
1344
|
}
|
|
1332
|
-
async function
|
|
1345
|
+
async function Ae(t, n = {}) {
|
|
1333
1346
|
if (n.signal?.aborted) return {
|
|
1334
|
-
result:
|
|
1347
|
+
result: De(),
|
|
1335
1348
|
runTime: 0
|
|
1336
1349
|
};
|
|
1337
1350
|
let r = await i(n.wasmUrl);
|
|
1338
1351
|
if (n.signal?.aborted) return {
|
|
1339
|
-
result:
|
|
1352
|
+
result: De(),
|
|
1340
1353
|
runTime: 0
|
|
1341
1354
|
};
|
|
1342
|
-
let a = n.useWorker ?? typeof window < "u" ?
|
|
1355
|
+
let a = n.useWorker ?? typeof window < "u" ? ke() : null;
|
|
1343
1356
|
if (!a) return e(t, n);
|
|
1344
1357
|
let { signal: o, onProgress: s, ...c } = n, l = {};
|
|
1345
1358
|
for (let [e, t] of Object.entries(c)) typeof t != "function" && (l[e] = t);
|
|
1346
1359
|
l.wasmUrl = r;
|
|
1347
|
-
let u = !!(s || o), d = `req_${++
|
|
1360
|
+
let u = !!(s || o), d = `req_${++Ee}`, f = performance.now();
|
|
1348
1361
|
return new Promise((e, n) => {
|
|
1349
1362
|
let r = {
|
|
1350
1363
|
id: d,
|
|
@@ -1358,24 +1371,24 @@ async function De(t, n = {}) {
|
|
|
1358
1371
|
};
|
|
1359
1372
|
if (o) {
|
|
1360
1373
|
let e = () => {
|
|
1361
|
-
let e =
|
|
1374
|
+
let e = W.get(d);
|
|
1362
1375
|
if (!e) return;
|
|
1363
|
-
let t =
|
|
1364
|
-
|
|
1376
|
+
let t = W.keys().next().value;
|
|
1377
|
+
W.delete(d), e.cleanupAbort?.(), t === d && Oe();
|
|
1365
1378
|
let n = (performance.now() - e.startTime) / 1e3;
|
|
1366
1379
|
e.resolve({
|
|
1367
|
-
result:
|
|
1380
|
+
result: De(e.lastIncumbent, e.lastProgress),
|
|
1368
1381
|
runTime: n
|
|
1369
1382
|
});
|
|
1370
1383
|
};
|
|
1371
1384
|
o.addEventListener("abort", e, { once: !0 }), r.cleanupAbort = () => o.removeEventListener("abort", e);
|
|
1372
1385
|
}
|
|
1373
|
-
|
|
1386
|
+
W.set(d, r), G(a);
|
|
1374
1387
|
});
|
|
1375
1388
|
}
|
|
1376
1389
|
//#endregion
|
|
1377
1390
|
//#region src/modeler/solvers/highs/solver.ts
|
|
1378
|
-
function
|
|
1391
|
+
function je(e, t) {
|
|
1379
1392
|
if (typeof t == "number") switch (t) {
|
|
1380
1393
|
case 0: return "NotSolved";
|
|
1381
1394
|
case 1:
|
|
@@ -1434,8 +1447,8 @@ function Oe(e, t) {
|
|
|
1434
1447
|
let r = n.toLowerCase();
|
|
1435
1448
|
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";
|
|
1436
1449
|
}
|
|
1437
|
-
function
|
|
1438
|
-
switch (
|
|
1450
|
+
function Me(e, t, n) {
|
|
1451
|
+
switch (je(e, t)) {
|
|
1439
1452
|
case "Optimal": return "Optimal";
|
|
1440
1453
|
case "Infeasible": return "Infeasible";
|
|
1441
1454
|
case "Unbounded": return "Unbounded";
|
|
@@ -1452,37 +1465,37 @@ function ke(e, t, n) {
|
|
|
1452
1465
|
default: return "Unknown";
|
|
1453
1466
|
}
|
|
1454
1467
|
}
|
|
1455
|
-
var
|
|
1468
|
+
var K = class e {
|
|
1456
1469
|
static capabilities = {
|
|
1457
1470
|
supportsMIP: !0,
|
|
1458
1471
|
supportsQP: !0,
|
|
1459
1472
|
supportsWarmStart: !0
|
|
1460
1473
|
};
|
|
1461
1474
|
name = "HiGHS";
|
|
1462
|
-
version = "1.15.
|
|
1475
|
+
version = "1.15.1";
|
|
1463
1476
|
capabilities = e.capabilities;
|
|
1464
1477
|
options;
|
|
1465
1478
|
constructor(e = {}) {
|
|
1466
1479
|
this.options = e;
|
|
1467
1480
|
}
|
|
1468
1481
|
async solve(e, t = {}, n = {}) {
|
|
1469
|
-
let r =
|
|
1482
|
+
let r = F(t), i = r ? n : t, a = {
|
|
1470
1483
|
...this.options,
|
|
1471
1484
|
...i
|
|
1472
1485
|
}, o = e.objective.constant || 0;
|
|
1473
1486
|
for (let t of e.variables) A(t);
|
|
1474
|
-
let { lpString: s, nameToVar: c, nameToConstraint: l } = r ? t :
|
|
1487
|
+
let { lpString: s, nameToVar: c, nameToConstraint: l } = r ? t : L(e, { relax: a.relax }), u = Object.create(null), d = !1, f = /* @__PURE__ */ new Set();
|
|
1475
1488
|
for (let [e, t] of c.entries()) {
|
|
1476
1489
|
f.add(t);
|
|
1477
|
-
let n =
|
|
1490
|
+
let n = ae(t);
|
|
1478
1491
|
n !== void 0 && (u[e] = n, d = !0);
|
|
1479
1492
|
}
|
|
1480
1493
|
for (let t = 0; t < e.variables.length; t++) {
|
|
1481
1494
|
let n = e.variables[t];
|
|
1482
1495
|
if (!f.has(n)) {
|
|
1483
|
-
let e =
|
|
1496
|
+
let e = ae(n);
|
|
1484
1497
|
if (e !== void 0) {
|
|
1485
|
-
let r =
|
|
1498
|
+
let r = I(n.name, "x", t);
|
|
1486
1499
|
Object.prototype.hasOwnProperty.call(u, r) || (u[r] = e, d = !0);
|
|
1487
1500
|
}
|
|
1488
1501
|
}
|
|
@@ -1493,13 +1506,13 @@ var J = class e {
|
|
|
1493
1506
|
...o === 0 ? {} : { objectiveOffset: o },
|
|
1494
1507
|
initialValues: d ? u : void 0
|
|
1495
1508
|
});
|
|
1496
|
-
let { result: m, runTime: h } = await
|
|
1509
|
+
let { result: m, runTime: h } = await Ae(s, p), g = m?.ObjectiveOffsetApplied ? 0 : o, _ = je(m?.Status, m?.StatusCode), v = a.relax ? !1 : typeof m?.IsMip == "boolean" ? m.IsMip : e.variables.some((e) => e.type === "Integer" || e.type === "Binary"), y;
|
|
1497
1510
|
if (typeof m?.HasPrimalSolution == "boolean") y = m.HasPrimalSolution;
|
|
1498
1511
|
else {
|
|
1499
1512
|
let e = m?.Columns ? Object.values(m.Columns) : [], t = e.length > 0 && e.some((e) => typeof e?.Primal == "number" && Number.isFinite(e.Primal)), n = typeof m?.ObjectiveValue == "number" && Number.isFinite(m.ObjectiveValue);
|
|
1500
1513
|
y = _ === "Infeasible" || _ === "Unbounded" || _ === "InfeasibleOrUnbounded" || _ === "Error" || _ === "NotSolved" ? !1 : _ === "Optimal" || _ === "Feasible" ? n || t : n && (e.length === 0 || t);
|
|
1501
1514
|
}
|
|
1502
|
-
let b =
|
|
1515
|
+
let b = Me(m?.Status, m?.StatusCode, y), x = null;
|
|
1503
1516
|
y && typeof m?.ObjectiveValue == "number" && Number.isFinite(m.ObjectiveValue) && (x = m.ObjectiveValue + g);
|
|
1504
1517
|
let S, C, w;
|
|
1505
1518
|
if (typeof m?.MipDualBound == "number" && Number.isFinite(m.MipDualBound) ? S = m.MipDualBound + g : !v && _ === "Optimal" && x !== null && (S = x), x !== null && S !== void 0 && Number.isFinite(S) && (w = Math.abs(x - S)), g !== 0 && v && x !== null && S !== void 0 && w !== void 0) {
|
|
@@ -1574,14 +1587,14 @@ var J = class e {
|
|
|
1574
1587
|
raw: m
|
|
1575
1588
|
};
|
|
1576
1589
|
}
|
|
1577
|
-
},
|
|
1578
|
-
function
|
|
1579
|
-
|
|
1590
|
+
}, Ne = K;
|
|
1591
|
+
function Pe() {
|
|
1592
|
+
Ce("highs", (e) => new K(e)), we((e) => new K(e));
|
|
1580
1593
|
}
|
|
1581
|
-
|
|
1594
|
+
Pe();
|
|
1582
1595
|
//#endregion
|
|
1583
1596
|
//#region src/modeler/solvers/mock.ts
|
|
1584
|
-
var
|
|
1597
|
+
var Fe = class {
|
|
1585
1598
|
name;
|
|
1586
1599
|
capabilities;
|
|
1587
1600
|
options;
|
|
@@ -1593,7 +1606,7 @@ var Me = class {
|
|
|
1593
1606
|
}, this.options = e;
|
|
1594
1607
|
}
|
|
1595
1608
|
async solve(e, t = {}, n = {}) {
|
|
1596
|
-
let r =
|
|
1609
|
+
let r = F(t) ? n : t, i = {
|
|
1597
1610
|
...this.options,
|
|
1598
1611
|
...r
|
|
1599
1612
|
}, a = !!(i.values && Object.keys(i.values).length > 0 || i.boolValues && Object.keys(i.boolValues).length > 0);
|
|
@@ -1681,29 +1694,29 @@ var Me = class {
|
|
|
1681
1694
|
};
|
|
1682
1695
|
}
|
|
1683
1696
|
};
|
|
1684
|
-
function
|
|
1685
|
-
|
|
1697
|
+
function Ie() {
|
|
1698
|
+
Ce("mock", (e) => new Fe(e));
|
|
1686
1699
|
}
|
|
1687
|
-
|
|
1700
|
+
Ie();
|
|
1688
1701
|
//#endregion
|
|
1689
1702
|
//#region src/modeler/solution-validator.ts
|
|
1690
|
-
function
|
|
1703
|
+
function Le(e, t) {
|
|
1691
1704
|
if (e === void 0) return 1e-6;
|
|
1692
1705
|
if (typeof e != "number" || !Number.isFinite(e) || e < 0) throw Error(`Invalid ${t}: expected a finite non-negative number, received ${String(e)}.`);
|
|
1693
1706
|
return e;
|
|
1694
1707
|
}
|
|
1695
|
-
function
|
|
1696
|
-
let n =
|
|
1708
|
+
function Re(e, t = {}) {
|
|
1709
|
+
let n = Le(t.feasibilityTolerance, "feasibilityTolerance"), r = Le(t.integralityTolerance, "integralityTolerance"), i = t.evaluateLogicalConstraints === void 0 || !!t.evaluateLogicalConstraints, a = t.values !== void 0 && t.values !== null;
|
|
1697
1710
|
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.");
|
|
1698
|
-
let o = t.values, s = [], c = Object.create(null), l = [],
|
|
1711
|
+
let o = t.values, s = [], c = Object.create(null), l = [], u = [], p = 0, m = (e) => {
|
|
1699
1712
|
typeof e == "number" && !Number.isNaN(e) && e > p && (p = e);
|
|
1700
1713
|
}, h = (e) => {
|
|
1701
1714
|
s.push(e), Object.prototype.hasOwnProperty.call(c, e.name) || (c[e.name] = []), c[e.name].push(e), e.type !== "missing_value" && e.type !== "unchecked_constraint" && m(e.violation);
|
|
1702
|
-
}, g = /* @__PURE__ */ new Map(), _ = /* @__PURE__ */ new Map(),
|
|
1715
|
+
}, g = /* @__PURE__ */ new Map(), _ = /* @__PURE__ */ new Map(), v = 0, b = 0, x = 0, S = 0;
|
|
1703
1716
|
for (let t of e.variables) {
|
|
1704
1717
|
let e = a ? Object.prototype.hasOwnProperty.call(o, t.name) ? o[t.name] : void 0 : t.value;
|
|
1705
1718
|
if (e == null) {
|
|
1706
|
-
|
|
1719
|
+
u.push(t.name), h({
|
|
1707
1720
|
type: "missing_value",
|
|
1708
1721
|
target: "variable",
|
|
1709
1722
|
name: t.name,
|
|
@@ -1724,9 +1737,9 @@ function Fe(e, t = {}) {
|
|
|
1724
1737
|
});
|
|
1725
1738
|
continue;
|
|
1726
1739
|
}
|
|
1727
|
-
g.set(t, e),
|
|
1728
|
-
let i = t.type === "Binary" || t.type === "BINARY", s = i || t.type === "Integer" || t.type === "INTEGER", c = i ? Math.max(0, t.lb) : t.lb, l = i ? Math.min(1, t.ub) : t.ub,
|
|
1729
|
-
if (!
|
|
1740
|
+
g.set(t, e), v++;
|
|
1741
|
+
let i = t.type === "Binary" || t.type === "BINARY", s = i || t.type === "Integer" || t.type === "INTEGER", c = i ? Math.max(0, t.lb) : t.lb, l = i ? Math.min(1, t.ub) : t.ub, d = typeof t.lb == "number" && !Number.isNaN(t.lb) && t.lb !== Infinity, f = typeof t.ub == "number" && !Number.isNaN(t.ub) && t.ub !== -Infinity;
|
|
1742
|
+
if (!d) h({
|
|
1730
1743
|
type: "lower_bound",
|
|
1731
1744
|
target: "variable",
|
|
1732
1745
|
name: t.name,
|
|
@@ -1748,7 +1761,7 @@ function Fe(e, t = {}) {
|
|
|
1748
1761
|
message: `Variable "${t.name}" value (${e}) violates lower bound (${c}) by ${i}.`
|
|
1749
1762
|
});
|
|
1750
1763
|
}
|
|
1751
|
-
if (!
|
|
1764
|
+
if (!f) h({
|
|
1752
1765
|
type: "upper_bound",
|
|
1753
1766
|
target: "variable",
|
|
1754
1767
|
name: t.name,
|
|
@@ -1770,7 +1783,7 @@ function Fe(e, t = {}) {
|
|
|
1770
1783
|
message: `Variable "${t.name}" value (${e}) violates upper bound (${l}) by ${i}.`
|
|
1771
1784
|
});
|
|
1772
1785
|
}
|
|
1773
|
-
if (
|
|
1786
|
+
if (d && f && c > l && c - e <= n && e - l <= n) {
|
|
1774
1787
|
let n = c - l;
|
|
1775
1788
|
h({
|
|
1776
1789
|
type: "lower_bound",
|
|
@@ -1801,7 +1814,7 @@ function Fe(e, t = {}) {
|
|
|
1801
1814
|
for (let t of e.boolVars) {
|
|
1802
1815
|
let e = a ? Object.prototype.hasOwnProperty.call(o, t.name) ? o[t.name] : void 0 : t.value;
|
|
1803
1816
|
if (e == null) {
|
|
1804
|
-
|
|
1817
|
+
u.push(t.name), h({
|
|
1805
1818
|
type: "missing_value",
|
|
1806
1819
|
target: "bool_variable",
|
|
1807
1820
|
name: t.name,
|
|
@@ -1905,7 +1918,7 @@ function Fe(e, t = {}) {
|
|
|
1905
1918
|
})) : (x++, m(e.violation));
|
|
1906
1919
|
}
|
|
1907
1920
|
let T = (e) => {
|
|
1908
|
-
if (e instanceof
|
|
1921
|
+
if (e instanceof d) return _.has(e) ? {
|
|
1909
1922
|
ok: !0,
|
|
1910
1923
|
value: _.get(e),
|
|
1911
1924
|
violation: 0
|
|
@@ -1913,7 +1926,7 @@ function Fe(e, t = {}) {
|
|
|
1913
1926
|
ok: !1,
|
|
1914
1927
|
reason: `missing or invalid value for Boolean variable "${e.name}"`
|
|
1915
1928
|
};
|
|
1916
|
-
if (e instanceof
|
|
1929
|
+
if (e instanceof y) {
|
|
1917
1930
|
let t = w(e, 0);
|
|
1918
1931
|
if (t.status === "unchecked") return {
|
|
1919
1932
|
ok: !1,
|
|
@@ -1932,7 +1945,7 @@ function Fe(e, t = {}) {
|
|
|
1932
1945
|
violation: 0
|
|
1933
1946
|
};
|
|
1934
1947
|
}
|
|
1935
|
-
if (e instanceof
|
|
1948
|
+
if (e instanceof f) switch (e.op) {
|
|
1936
1949
|
case "not": {
|
|
1937
1950
|
let t = T(e.children[0]);
|
|
1938
1951
|
return t.ok ? {
|
|
@@ -2044,17 +2057,17 @@ function Fe(e, t = {}) {
|
|
|
2044
2057
|
message: `Logical constraint "${r}" evaluated to false.`
|
|
2045
2058
|
});
|
|
2046
2059
|
}
|
|
2047
|
-
let E =
|
|
2060
|
+
let E = v === e.variables.length && b === e.boolVars.length && x === e.constraints.length && S === e.logicalConstraints.length && l.length === 0 && u.length === 0;
|
|
2048
2061
|
return {
|
|
2049
2062
|
valid: E && s.length === 0,
|
|
2050
2063
|
complete: E,
|
|
2051
2064
|
violations: s,
|
|
2052
2065
|
violationsByName: c,
|
|
2053
2066
|
uncheckedConstraints: l,
|
|
2054
|
-
missingVariables:
|
|
2067
|
+
missingVariables: u,
|
|
2055
2068
|
maxViolation: p,
|
|
2056
2069
|
summary: {
|
|
2057
|
-
checkedVariables:
|
|
2070
|
+
checkedVariables: v,
|
|
2058
2071
|
totalVariables: e.variables.length,
|
|
2059
2072
|
checkedBoolVariables: b,
|
|
2060
2073
|
totalBoolVariables: e.boolVars.length,
|
|
@@ -2067,10 +2080,10 @@ function Fe(e, t = {}) {
|
|
|
2067
2080
|
}
|
|
2068
2081
|
//#endregion
|
|
2069
2082
|
//#region src/modeler/big-m.ts
|
|
2070
|
-
function
|
|
2083
|
+
function ze(e, t) {
|
|
2071
2084
|
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}.`);
|
|
2072
2085
|
}
|
|
2073
|
-
function
|
|
2086
|
+
function Be(e, t, n) {
|
|
2074
2087
|
let r = e.constant === void 0 ? 0 : e.constant;
|
|
2075
2088
|
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}).`);
|
|
2076
2089
|
let i = t - r;
|
|
@@ -2081,8 +2094,8 @@ function Y(e, t, n) {
|
|
|
2081
2094
|
}
|
|
2082
2095
|
return i;
|
|
2083
2096
|
}
|
|
2084
|
-
function
|
|
2085
|
-
let r =
|
|
2097
|
+
function q(e, t, n) {
|
|
2098
|
+
let r = Be(e, t, n), i = 0;
|
|
2086
2099
|
for (let [t, r] of e.terms) {
|
|
2087
2100
|
if (r === 0) continue;
|
|
2088
2101
|
let e;
|
|
@@ -2102,8 +2115,8 @@ function Le(e, t, n) {
|
|
|
2102
2115
|
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.`);
|
|
2103
2116
|
return o;
|
|
2104
2117
|
}
|
|
2105
|
-
function
|
|
2106
|
-
let r =
|
|
2118
|
+
function J(e, t, n) {
|
|
2119
|
+
let r = Be(e, t, n), i = 0;
|
|
2107
2120
|
for (let [t, r] of e.terms) {
|
|
2108
2121
|
if (r === 0) continue;
|
|
2109
2122
|
let e;
|
|
@@ -2123,10 +2136,10 @@ function Re(e, t, n) {
|
|
|
2123
2136
|
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.`);
|
|
2124
2137
|
return o;
|
|
2125
2138
|
}
|
|
2126
|
-
function
|
|
2127
|
-
if (!(e instanceof
|
|
2139
|
+
function Y(e, t, n, r, i, a, o) {
|
|
2140
|
+
if (!(e instanceof M && (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}].`);
|
|
2128
2141
|
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.`);
|
|
2129
|
-
let s =
|
|
2142
|
+
let s = Be(t, r, o);
|
|
2130
2143
|
if (i !== 0 && i !== 1) throw Error(`Invalid activeValue: ${i}. Indicator activation value must be 0 or 1.`);
|
|
2131
2144
|
if (n !== "<=" && n !== ">=") throw Error(`Invalid indicator sense for "${o}": expected "<=" or ">=", received "${String(n)}".`);
|
|
2132
2145
|
if (!Number.isFinite(a) || a < 0) throw Error(`Invalid Big-M value for indicator constraint "${o}": expected a finite non-negative number, received ${a}.`);
|
|
@@ -2137,11 +2150,532 @@ function X(e, t, n, r, i, a, o) {
|
|
|
2137
2150
|
let d = /* @__PURE__ */ new Map();
|
|
2138
2151
|
for (let [e, n] of t.terms) n !== 0 && d.set(e, n);
|
|
2139
2152
|
return l !== 0 && d.set(e, l), {
|
|
2140
|
-
lhs: new
|
|
2153
|
+
lhs: new C(d, 0),
|
|
2141
2154
|
rhs: u
|
|
2142
2155
|
};
|
|
2143
2156
|
}
|
|
2144
2157
|
//#endregion
|
|
2158
|
+
//#region src/modeler/linearizer.ts
|
|
2159
|
+
function X(e, t = 0) {
|
|
2160
|
+
return new C(new Map(e), t);
|
|
2161
|
+
}
|
|
2162
|
+
function Ve(e, t, n, r) {
|
|
2163
|
+
let i = [...e], a = [...n], o = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map();
|
|
2164
|
+
for (let e of n) s.set(e, e.name);
|
|
2165
|
+
let c = new Set(e.map((e) => e.name)), l = 0;
|
|
2166
|
+
function u(e) {
|
|
2167
|
+
let t;
|
|
2168
|
+
do
|
|
2169
|
+
t = `__washi_${e}_${++l}`;
|
|
2170
|
+
while (c.has(t));
|
|
2171
|
+
return c.add(t), t;
|
|
2172
|
+
}
|
|
2173
|
+
for (let e of t) {
|
|
2174
|
+
let t = e.name;
|
|
2175
|
+
c.has(t) ? t = u(`bool_${e.name}`) : c.add(t);
|
|
2176
|
+
let n = new M({
|
|
2177
|
+
name: t,
|
|
2178
|
+
type: "Binary",
|
|
2179
|
+
lb: 0,
|
|
2180
|
+
ub: 1
|
|
2181
|
+
});
|
|
2182
|
+
o.set(e, n), i.push(n);
|
|
2183
|
+
}
|
|
2184
|
+
function p(e, t) {
|
|
2185
|
+
if (e instanceof He) return e.wrappedVar;
|
|
2186
|
+
if (e instanceof d) {
|
|
2187
|
+
let n = o.get(e);
|
|
2188
|
+
if (!n) throw Error(`Unregistered BoolVar "${e.name}" in logical constraint "${t}".`);
|
|
2189
|
+
return n;
|
|
2190
|
+
}
|
|
2191
|
+
let n = new M({
|
|
2192
|
+
name: u("expr"),
|
|
2193
|
+
type: "Binary",
|
|
2194
|
+
lb: 0,
|
|
2195
|
+
ub: 1
|
|
2196
|
+
});
|
|
2197
|
+
return i.push(n), h(n, e, t), n;
|
|
2198
|
+
}
|
|
2199
|
+
function m(e, t, n, r) {
|
|
2200
|
+
let i = new y(X([
|
|
2201
|
+
[e, 1],
|
|
2202
|
+
[t, -1],
|
|
2203
|
+
[n, -1]
|
|
2204
|
+
], 0), "<=", 0, `${r}_xor_1`), o = new y(X([
|
|
2205
|
+
[e, 1],
|
|
2206
|
+
[t, -1],
|
|
2207
|
+
[n, 1]
|
|
2208
|
+
], 0), ">=", 0, `${r}_xor_2`), c = new y(X([
|
|
2209
|
+
[e, 1],
|
|
2210
|
+
[n, -1],
|
|
2211
|
+
[t, 1]
|
|
2212
|
+
], 0), ">=", 0, `${r}_xor_3`), l = new y(X([
|
|
2213
|
+
[e, 1],
|
|
2214
|
+
[t, 1],
|
|
2215
|
+
[n, 1]
|
|
2216
|
+
], 0), "<=", 2, `${r}_xor_4`);
|
|
2217
|
+
a.push(i, o, c, l), s.set(i, r), s.set(o, r), s.set(c, r), s.set(l, r);
|
|
2218
|
+
}
|
|
2219
|
+
function h(e, t, n) {
|
|
2220
|
+
if (t instanceof d) {
|
|
2221
|
+
let r = o.get(t), i = new y(X([[e, 1], [r, -1]], 0), "==", 0, `${n}_equiv`);
|
|
2222
|
+
a.push(i), s.set(i, n);
|
|
2223
|
+
return;
|
|
2224
|
+
}
|
|
2225
|
+
if (t instanceof f) {
|
|
2226
|
+
if (t.op === "not") {
|
|
2227
|
+
let r = p(t.children[0], n), i = new y(X([[e, 1], [r, 1]], 0), "==", 1, `${n}_not`);
|
|
2228
|
+
a.push(i), s.set(i, n);
|
|
2229
|
+
return;
|
|
2230
|
+
}
|
|
2231
|
+
if (t.op === "and") {
|
|
2232
|
+
let r = t.children.map((e) => p(e, n));
|
|
2233
|
+
for (let t = 0; t < r.length; t++) {
|
|
2234
|
+
let i = new y(X([[e, 1], [r[t], -1]], 0), "<=", 0, `${n}_and_ub_${t}`);
|
|
2235
|
+
a.push(i), s.set(i, n);
|
|
2236
|
+
}
|
|
2237
|
+
let i = new y(X([[e, 1], ...r.map((e) => [e, -1])], 0), ">=", 1 - r.length, `${n}_and_lb`);
|
|
2238
|
+
a.push(i), s.set(i, n);
|
|
2239
|
+
return;
|
|
2240
|
+
}
|
|
2241
|
+
if (t.op === "or") {
|
|
2242
|
+
let r = t.children.map((e) => p(e, n));
|
|
2243
|
+
for (let t = 0; t < r.length; t++) {
|
|
2244
|
+
let i = new y(X([[e, 1], [r[t], -1]], 0), ">=", 0, `${n}_or_lb_${t}`);
|
|
2245
|
+
a.push(i), s.set(i, n);
|
|
2246
|
+
}
|
|
2247
|
+
let i = new y(X([[e, 1], ...r.map((e) => [e, -1])], 0), "<=", 0, `${n}_or_ub`);
|
|
2248
|
+
a.push(i), s.set(i, n);
|
|
2249
|
+
return;
|
|
2250
|
+
}
|
|
2251
|
+
if (t.op === "implies") {
|
|
2252
|
+
let r = p(t.children[0], n), i = p(t.children[1], n), o = new y(X([
|
|
2253
|
+
[e, 1],
|
|
2254
|
+
[i, -1],
|
|
2255
|
+
[r, 1]
|
|
2256
|
+
], 0), ">=", 0, `${n}_imp_1`), c = new y(X([
|
|
2257
|
+
[e, 1],
|
|
2258
|
+
[r, 1],
|
|
2259
|
+
[i, -1]
|
|
2260
|
+
], 0), "<=", 1, `${n}_imp_2`);
|
|
2261
|
+
a.push(o, c), s.set(o, n), s.set(c, n);
|
|
2262
|
+
return;
|
|
2263
|
+
}
|
|
2264
|
+
if (t.op === "xor") {
|
|
2265
|
+
if (t.children.length === 0) {
|
|
2266
|
+
let t = new y(X([[e, 1]], 0), "==", 0, `${n}_xor_empty`);
|
|
2267
|
+
a.push(t), s.set(t, n);
|
|
2268
|
+
return;
|
|
2269
|
+
}
|
|
2270
|
+
if (t.children.length === 1) {
|
|
2271
|
+
let r = p(t.children[0], n), i = new y(X([[e, 1], [r, -1]], 0), "==", 0, `${n}_xor_single`);
|
|
2272
|
+
a.push(i), s.set(i, n);
|
|
2273
|
+
return;
|
|
2274
|
+
}
|
|
2275
|
+
let r = t.children.map((e) => p(e, n)), o = r[0];
|
|
2276
|
+
for (let e = 1; e < r.length - 1; e++) {
|
|
2277
|
+
let t = new M({
|
|
2278
|
+
name: u(`xor_fold_${e}`),
|
|
2279
|
+
type: "Binary",
|
|
2280
|
+
lb: 0,
|
|
2281
|
+
ub: 1
|
|
2282
|
+
});
|
|
2283
|
+
i.push(t), m(t, o, r[e], `${n}_xor_fold_${e}`), o = t;
|
|
2284
|
+
}
|
|
2285
|
+
m(e, o, r[r.length - 1], n);
|
|
2286
|
+
return;
|
|
2287
|
+
}
|
|
2288
|
+
}
|
|
2289
|
+
throw Error(`Unsupported logical element in equivalence linearization: ${t}`);
|
|
2290
|
+
}
|
|
2291
|
+
for (let e of r) {
|
|
2292
|
+
let t = e.name, n = e.expr;
|
|
2293
|
+
g(n, t);
|
|
2294
|
+
}
|
|
2295
|
+
function g(e, t) {
|
|
2296
|
+
if (e instanceof d) {
|
|
2297
|
+
let n = new y(X([[o.get(e), 1]], 0), ">=", 1, t);
|
|
2298
|
+
a.push(n), s.set(n, t);
|
|
2299
|
+
return;
|
|
2300
|
+
}
|
|
2301
|
+
if (e instanceof f) {
|
|
2302
|
+
if (e.op === "not") {
|
|
2303
|
+
let n = e.children[0];
|
|
2304
|
+
if (n instanceof d) {
|
|
2305
|
+
let e = new y(X([[o.get(n), 1]], 0), "<=", 0, t);
|
|
2306
|
+
a.push(e), s.set(e, t);
|
|
2307
|
+
return;
|
|
2308
|
+
}
|
|
2309
|
+
let r = new y(X([[p(n, t), 1]], 0), "<=", 0, t);
|
|
2310
|
+
a.push(r), s.set(r, t);
|
|
2311
|
+
return;
|
|
2312
|
+
}
|
|
2313
|
+
if (e.op === "and") {
|
|
2314
|
+
for (let n = 0; n < e.children.length; n++) g(e.children[n], `${t}_and_${n}`);
|
|
2315
|
+
return;
|
|
2316
|
+
}
|
|
2317
|
+
if (e.op === "or") {
|
|
2318
|
+
if (e.children.every((e) => e instanceof d || e instanceof f)) {
|
|
2319
|
+
let n = new y(X(e.children.map((e) => p(e, t)).map((e) => [e, 1]), 0), ">=", 1, t);
|
|
2320
|
+
a.push(n), s.set(n, t);
|
|
2321
|
+
return;
|
|
2322
|
+
}
|
|
2323
|
+
let n = [];
|
|
2324
|
+
for (let r = 0; r < e.children.length; r++) {
|
|
2325
|
+
let o = e.children[r], c = new M({
|
|
2326
|
+
name: u(`or_branch_${r}`),
|
|
2327
|
+
type: "Binary",
|
|
2328
|
+
lb: 0,
|
|
2329
|
+
ub: 1
|
|
2330
|
+
});
|
|
2331
|
+
if (i.push(c), n.push(c), o instanceof y) _(c, o, 1, `${t}_or_branch_${r}`, t);
|
|
2332
|
+
else {
|
|
2333
|
+
let e = p(o, t), n = new y(X([[c, 1], [e, -1]], 0), "<=", 0, `${t}_or_bool_${r}`);
|
|
2334
|
+
a.push(n), s.set(n, t);
|
|
2335
|
+
}
|
|
2336
|
+
}
|
|
2337
|
+
let r = new y(X(n.map((e) => [e, 1]), 0), ">=", 1, t);
|
|
2338
|
+
a.push(r), s.set(r, t);
|
|
2339
|
+
return;
|
|
2340
|
+
}
|
|
2341
|
+
if (e.op === "xor") {
|
|
2342
|
+
if (e.children.length === 0) {
|
|
2343
|
+
let e = new M({
|
|
2344
|
+
name: u("unsat"),
|
|
2345
|
+
type: "Binary",
|
|
2346
|
+
lb: 0,
|
|
2347
|
+
ub: 0
|
|
2348
|
+
});
|
|
2349
|
+
i.push(e);
|
|
2350
|
+
let n = new y(X([[e, 1]], 0), ">=", 1, t);
|
|
2351
|
+
a.push(n), s.set(n, t);
|
|
2352
|
+
return;
|
|
2353
|
+
}
|
|
2354
|
+
if (e.children.length === 1) {
|
|
2355
|
+
g(e.children[0], t);
|
|
2356
|
+
return;
|
|
2357
|
+
}
|
|
2358
|
+
let n = e.children.map((e) => p(e, t));
|
|
2359
|
+
if (n.length === 2) {
|
|
2360
|
+
let e = new y(X([[n[0], 1], [n[1], 1]], 0), "==", 1, t);
|
|
2361
|
+
a.push(e), s.set(e, t);
|
|
2362
|
+
return;
|
|
2363
|
+
}
|
|
2364
|
+
let r = n[0];
|
|
2365
|
+
for (let e = 1; e < n.length - 1; e++) {
|
|
2366
|
+
let a = new M({
|
|
2367
|
+
name: u(`xor_fold_${e}`),
|
|
2368
|
+
type: "Binary",
|
|
2369
|
+
lb: 0,
|
|
2370
|
+
ub: 1
|
|
2371
|
+
});
|
|
2372
|
+
i.push(a), m(a, r, n[e], `${t}_xor_fold_${e}`), r = a;
|
|
2373
|
+
}
|
|
2374
|
+
let o = n[n.length - 1], c = new y(X([[r, 1], [o, 1]], 0), "==", 1, t);
|
|
2375
|
+
a.push(c), s.set(c, t);
|
|
2376
|
+
return;
|
|
2377
|
+
}
|
|
2378
|
+
if (e.op === "implies") {
|
|
2379
|
+
let [n, r] = e.children;
|
|
2380
|
+
if (n instanceof y && n.lhs.terms.size === 1 && n.lhs.constant === 0) {
|
|
2381
|
+
let [[e, i]] = Array.from(n.lhs.terms.entries());
|
|
2382
|
+
if ((e.type === "Binary" || e.type === "Integer" && e.lb === 0 && e.ub === 1) && i === 1) {
|
|
2383
|
+
let i = null;
|
|
2384
|
+
if (n.sense === "==" && n.rhs === 1 ? i = 1 : n.sense === "==" && n.rhs === 0 || n.sense === "<=" && n.rhs === 0 ? i = 0 : n.sense === ">=" && n.rhs === 1 && (i = 1), i !== null && r instanceof y) {
|
|
2385
|
+
_(e, r, i, t, t);
|
|
2386
|
+
return;
|
|
2387
|
+
}
|
|
2388
|
+
}
|
|
2389
|
+
}
|
|
2390
|
+
let c;
|
|
2391
|
+
if (n instanceof y ? (c = new M({
|
|
2392
|
+
name: u("ante"),
|
|
2393
|
+
type: "Binary",
|
|
2394
|
+
lb: 0,
|
|
2395
|
+
ub: 1
|
|
2396
|
+
}), i.push(c), _(c, n, 1, `${t}_ante_active`, t)) : c = p(n, t), r instanceof y) {
|
|
2397
|
+
_(c, r, 1, t, t);
|
|
2398
|
+
return;
|
|
2399
|
+
}
|
|
2400
|
+
if (r instanceof d) {
|
|
2401
|
+
let e = new y(X([[o.get(r), 1], [c, -1]], 0), ">=", 0, t);
|
|
2402
|
+
a.push(e), s.set(e, t);
|
|
2403
|
+
return;
|
|
2404
|
+
}
|
|
2405
|
+
if (r instanceof f) {
|
|
2406
|
+
if (r.op === "and") {
|
|
2407
|
+
for (let e = 0; e < r.children.length; e++) g(new f("implies", [c instanceof M ? new He(c) : n, r.children[e]]), `${t}_and_${e}`);
|
|
2408
|
+
return;
|
|
2409
|
+
}
|
|
2410
|
+
if (r.op === "not") {
|
|
2411
|
+
let e = r.children[0], n = p(e, t), i = new y(X([[c, 1], [n, 1]], 0), "<=", 1, t);
|
|
2412
|
+
a.push(i), s.set(i, t);
|
|
2413
|
+
return;
|
|
2414
|
+
}
|
|
2415
|
+
let e = new y(X([[p(r, t), 1], [c, -1]], 0), ">=", 0, t);
|
|
2416
|
+
a.push(e), s.set(e, t);
|
|
2417
|
+
return;
|
|
2418
|
+
}
|
|
2419
|
+
}
|
|
2420
|
+
}
|
|
2421
|
+
throw Error(`Unsupported top-level logical constraint "${t}": ${e}`);
|
|
2422
|
+
}
|
|
2423
|
+
function _(e, t, n, r, i) {
|
|
2424
|
+
let { lhs: o, sense: c, rhs: l } = t;
|
|
2425
|
+
if (c === "<=" || c === ">=") {
|
|
2426
|
+
let t = Y(e, o, c, l, n, c === "<=" ? q(o, l, r) : J(o, l, r), r), u = new y(t.lhs, c, t.rhs, r);
|
|
2427
|
+
a.push(u), s.set(u, i);
|
|
2428
|
+
} else {
|
|
2429
|
+
let t = q(o, l, `${r}_le`), c = J(o, l, `${r}_ge`), u = Y(e, o, "<=", l, n, t, `${r}_le`), d = Y(e, o, ">=", l, n, c, `${r}_ge`), f = new y(u.lhs, "<=", u.rhs, `${r}_le`), p = new y(d.lhs, ">=", d.rhs, `${r}_ge`);
|
|
2430
|
+
a.push(f, p), s.set(f, i), s.set(p, i);
|
|
2431
|
+
}
|
|
2432
|
+
}
|
|
2433
|
+
return {
|
|
2434
|
+
variables: i,
|
|
2435
|
+
constraints: a,
|
|
2436
|
+
boolVarToBinary: o,
|
|
2437
|
+
constraintToOriginalName: s
|
|
2438
|
+
};
|
|
2439
|
+
}
|
|
2440
|
+
var He = class extends d {
|
|
2441
|
+
wrappedVar;
|
|
2442
|
+
constructor(e) {
|
|
2443
|
+
super(e.name), this.wrappedVar = e;
|
|
2444
|
+
}
|
|
2445
|
+
};
|
|
2446
|
+
//#endregion
|
|
2447
|
+
//#region src/decomposition/column-generation.ts
|
|
2448
|
+
async function Ue(e) {
|
|
2449
|
+
let t = e.master;
|
|
2450
|
+
if (!t) throw Error("A master Model must be provided for solveColumnGeneration.");
|
|
2451
|
+
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;
|
|
2452
|
+
if (!u) throw Error("The 'pricing' callback must be provided in ColumnGenerationOptions.");
|
|
2453
|
+
let d = [], f = null, p = 0, m = t.status;
|
|
2454
|
+
for (let e = 1; e <= r; e++) {
|
|
2455
|
+
p = e;
|
|
2456
|
+
let n = await t.relax(o, s);
|
|
2457
|
+
if (m = n, n !== "Optimal" && n !== "Feasible" || !t.solution) break;
|
|
2458
|
+
f = t.objectiveValue;
|
|
2459
|
+
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({
|
|
2460
|
+
iteration: e,
|
|
2461
|
+
duals: a,
|
|
2462
|
+
getDual: h,
|
|
2463
|
+
masterSolution: r,
|
|
2464
|
+
reducedCostTolerance: i,
|
|
2465
|
+
master: t
|
|
2466
|
+
}), _ = [];
|
|
2467
|
+
g && (Array.isArray(g) ? _.push(...g) : _.push(g));
|
|
2468
|
+
let v = [];
|
|
2469
|
+
for (let e of _) {
|
|
2470
|
+
let t = e.reducedCost;
|
|
2471
|
+
if (typeof t != "number" || !Number.isFinite(t)) {
|
|
2472
|
+
let n = 0, r = e.coefficients;
|
|
2473
|
+
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));
|
|
2474
|
+
else if (r instanceof Map) for (let [e, t] of r.entries()) n += t * h(e);
|
|
2475
|
+
else if (r && typeof r == "object") for (let [e, t] of Object.entries(r)) n += t * h(e);
|
|
2476
|
+
t = e.cost - n;
|
|
2477
|
+
}
|
|
2478
|
+
(l ? t > i : t < -i) && v.push(e);
|
|
2479
|
+
}
|
|
2480
|
+
if (c && c({
|
|
2481
|
+
iteration: e,
|
|
2482
|
+
relaxationObjective: f,
|
|
2483
|
+
columnsAdded: d.length + v.length,
|
|
2484
|
+
proposedColumns: v
|
|
2485
|
+
}), v.length === 0) break;
|
|
2486
|
+
for (let e of v) {
|
|
2487
|
+
let n = t.addColumn({
|
|
2488
|
+
name: e.name,
|
|
2489
|
+
type: e.type || "Continuous",
|
|
2490
|
+
lb: e.lb,
|
|
2491
|
+
ub: e.ub,
|
|
2492
|
+
cost: e.cost,
|
|
2493
|
+
coefficients: e.coefficients
|
|
2494
|
+
});
|
|
2495
|
+
d.push({
|
|
2496
|
+
variable: n,
|
|
2497
|
+
proposal: e
|
|
2498
|
+
});
|
|
2499
|
+
}
|
|
2500
|
+
}
|
|
2501
|
+
let h = f;
|
|
2502
|
+
a && (m === "Optimal" || m === "Feasible") && (m = await t.solve(o, s), h = t.objectiveValue);
|
|
2503
|
+
let g = {};
|
|
2504
|
+
for (let e of t.variables) e.value !== null && (g[e.name] = e.value);
|
|
2505
|
+
let _ = {
|
|
2506
|
+
status: m,
|
|
2507
|
+
objectiveValue: h,
|
|
2508
|
+
relaxationObjectiveValue: f,
|
|
2509
|
+
iterations: p,
|
|
2510
|
+
columnsAdded: d.length,
|
|
2511
|
+
generatedColumns: d,
|
|
2512
|
+
master: t,
|
|
2513
|
+
values: g
|
|
2514
|
+
};
|
|
2515
|
+
return t.decomposition = _, _;
|
|
2516
|
+
}
|
|
2517
|
+
//#endregion
|
|
2518
|
+
//#region src/modeler/objective.ts
|
|
2519
|
+
function We(e, t) {
|
|
2520
|
+
let n = e;
|
|
2521
|
+
if (n instanceof y || 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}\`)).`);
|
|
2522
|
+
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}\`)).`);
|
|
2523
|
+
if (typeof n == "number") {
|
|
2524
|
+
if (!Number.isFinite(n)) throw Error(`Invalid non-finite objective constant "${n}" passed to ${t}().`);
|
|
2525
|
+
return n;
|
|
2526
|
+
}
|
|
2527
|
+
if (typeof n == "string" || n instanceof C || n instanceof S || n instanceof M || 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;
|
|
2528
|
+
throw Error(`Invalid expression passed to ${t}(): expected a finite number, Var, LinExpr, QuadExpr, or arithmetic expression string.`);
|
|
2529
|
+
}
|
|
2530
|
+
function Ge(e) {
|
|
2531
|
+
return {
|
|
2532
|
+
expr: We(e, "maximize"),
|
|
2533
|
+
sense: "Maximize"
|
|
2534
|
+
};
|
|
2535
|
+
}
|
|
2536
|
+
function Ke(e) {
|
|
2537
|
+
return {
|
|
2538
|
+
expr: We(e, "minimize"),
|
|
2539
|
+
sense: "Minimize"
|
|
2540
|
+
};
|
|
2541
|
+
}
|
|
2542
|
+
//#endregion
|
|
2543
|
+
//#region src/decomposition/benders.ts
|
|
2544
|
+
function qe(e) {
|
|
2545
|
+
return !!(e && typeof e == "object" && "constraints" in e && "variables" in e && typeof e.solve == "function");
|
|
2546
|
+
}
|
|
2547
|
+
async function Je(e, t, n, r, i, a, o, s, c = 1) {
|
|
2548
|
+
let l = [];
|
|
2549
|
+
for (let r = 0; r < t.length; r++) {
|
|
2550
|
+
let a = t[r], o = a.lhs, s = a.sense, u = a.rhs - (o.constant || 0), d = [], f = [], p = 0;
|
|
2551
|
+
for (let [e, t] of o.terms.entries()) if (e.ownerModel === n || n.getVarByName(e.name) !== void 0) {
|
|
2552
|
+
f.push([e, t]);
|
|
2553
|
+
let n = i[e.name] ?? 0;
|
|
2554
|
+
p += t * n;
|
|
2555
|
+
} else d.push([e, t]);
|
|
2556
|
+
let m = u - p, h = new C();
|
|
2557
|
+
for (let [e, t] of d) h.addTerm(e, t);
|
|
2558
|
+
let g = new y(h, s, m, `__benders_link_${c}_${r}`);
|
|
2559
|
+
e.constraint(g), l.push({
|
|
2560
|
+
origConstraint: a,
|
|
2561
|
+
subConstr: g,
|
|
2562
|
+
masterTerms: f,
|
|
2563
|
+
baseRhs: u
|
|
2564
|
+
});
|
|
2565
|
+
}
|
|
2566
|
+
let u = await e.solve(o, {
|
|
2567
|
+
...s,
|
|
2568
|
+
relax: !0
|
|
2569
|
+
});
|
|
2570
|
+
if (u !== "Optimal" && u !== "Feasible") return null;
|
|
2571
|
+
let d = e.objectiveValue ?? 0, f = i[r.name] ?? 0, p = 1e-4;
|
|
2572
|
+
if (!(a ? f < d - p : f > d + p)) return null;
|
|
2573
|
+
let m = 0, h = /* @__PURE__ */ new Map(), g = new Set(l.map((e) => e.subConstr.name));
|
|
2574
|
+
for (let t of e.constraints) {
|
|
2575
|
+
if (g.has(t.name)) continue;
|
|
2576
|
+
let n = e.solution?.duals[t.name] ?? t.dual ?? 0;
|
|
2577
|
+
if (Math.abs(n) > 1e-12) {
|
|
2578
|
+
let e = t.rhs - (t.lhs.constant || 0);
|
|
2579
|
+
m += n * e;
|
|
2580
|
+
}
|
|
2581
|
+
}
|
|
2582
|
+
for (let t of l) {
|
|
2583
|
+
let n = e.solution?.duals[t.subConstr.name] ?? t.subConstr.dual ?? 0;
|
|
2584
|
+
if (Math.abs(n) > 1e-12) {
|
|
2585
|
+
m += n * t.baseRhs;
|
|
2586
|
+
for (let [e, r] of t.masterTerms) {
|
|
2587
|
+
let t = h.get(e) ?? 0;
|
|
2588
|
+
h.set(e, t + n * r);
|
|
2589
|
+
}
|
|
2590
|
+
}
|
|
2591
|
+
}
|
|
2592
|
+
let _ = new C();
|
|
2593
|
+
_.addTerm(r, 1);
|
|
2594
|
+
for (let [e, t] of h.entries()) Math.abs(t) > 1e-12 && _.addTerm(e, t);
|
|
2595
|
+
let v = new y(_, a ? ">=" : "<=", m, `__benders_opt_cut_${c}`), b = (n.objectiveValue ?? 0) - f + d;
|
|
2596
|
+
return {
|
|
2597
|
+
kind: "optimality",
|
|
2598
|
+
constraint: v,
|
|
2599
|
+
name: v.name,
|
|
2600
|
+
subproblemObjective: b
|
|
2601
|
+
};
|
|
2602
|
+
}
|
|
2603
|
+
async function Ye(e) {
|
|
2604
|
+
let t = e.master;
|
|
2605
|
+
if (!t) throw Error("A master Model must be provided for solveBenders.");
|
|
2606
|
+
let { subproblem: n, maxIterations: r = 100, gapTolerance: i = 1e-4, solver: a, solverOptions: o, onIteration: s } = e, c;
|
|
2607
|
+
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");
|
|
2608
|
+
let l = 0, u = 0, d = t.status, f, p, m, h = {}, g = null;
|
|
2609
|
+
for (let e = 1; e <= r; e++) {
|
|
2610
|
+
u = e;
|
|
2611
|
+
let r = await t.solve(a, o);
|
|
2612
|
+
if (d = r, r !== "Optimal" && r !== "Feasible") break;
|
|
2613
|
+
let _ = t.objectiveValue, v = t.sense.toLowerCase() === "minimize";
|
|
2614
|
+
v ? f = _ === null ? f : _ : p = _ === null ? p : _;
|
|
2615
|
+
let y = {};
|
|
2616
|
+
for (let e of t.variables) e.value !== null && (y[e.name] = e.value);
|
|
2617
|
+
let b = await n({
|
|
2618
|
+
iteration: e,
|
|
2619
|
+
masterValues: y,
|
|
2620
|
+
getMasterValue: (e) => typeof e == "string" ? y[e] ?? 0 : e.value ?? (e.name ? y[e.name] ?? 0 : 0),
|
|
2621
|
+
masterObjective: _,
|
|
2622
|
+
lowerBound: f,
|
|
2623
|
+
upperBound: p,
|
|
2624
|
+
master: t
|
|
2625
|
+
}), x = [];
|
|
2626
|
+
if (b) {
|
|
2627
|
+
if (qe(b)) {
|
|
2628
|
+
let n = b, r = n.linkingConstraints;
|
|
2629
|
+
c || (c = t.continuous("__benders_theta", { lb: 0 }), v ? t.objective(Ke(t.objectiveExpr.add(c))) : t.objective(Ge(t.objectiveExpr.sub(c))));
|
|
2630
|
+
let i = await Je(n, r, t, c, y, v, a, o, e);
|
|
2631
|
+
i && x.push(i);
|
|
2632
|
+
} else Array.isArray(b) ? x.push(...b) : x.push(b);
|
|
2633
|
+
}
|
|
2634
|
+
for (let e of x) if (typeof e.subproblemObjective == "number" && Number.isFinite(e.subproblemObjective)) {
|
|
2635
|
+
if (v) {
|
|
2636
|
+
let t = e.subproblemObjective;
|
|
2637
|
+
(p === void 0 || t < p) && (p = t, g = t, h = { ...y });
|
|
2638
|
+
} else {
|
|
2639
|
+
let t = e.subproblemObjective;
|
|
2640
|
+
(f === void 0 || t > f) && (f = t, g = t, h = { ...y });
|
|
2641
|
+
}
|
|
2642
|
+
}
|
|
2643
|
+
if (f !== void 0 && p !== void 0) {
|
|
2644
|
+
let e = Math.abs(p) + 1e-10;
|
|
2645
|
+
m = Math.abs(p - f) / e;
|
|
2646
|
+
}
|
|
2647
|
+
if (s && s({
|
|
2648
|
+
iteration: e,
|
|
2649
|
+
masterObjective: _,
|
|
2650
|
+
lowerBound: f,
|
|
2651
|
+
upperBound: p,
|
|
2652
|
+
cutsAdded: l + x.length,
|
|
2653
|
+
proposedCuts: x
|
|
2654
|
+
}), x.length === 0) {
|
|
2655
|
+
g = _, h = { ...y };
|
|
2656
|
+
break;
|
|
2657
|
+
}
|
|
2658
|
+
if (m !== void 0 && m <= i) break;
|
|
2659
|
+
for (let e of x) t.constraint(e.constraint, e.name), l++;
|
|
2660
|
+
}
|
|
2661
|
+
let _ = Object.keys(h).length > 0 ? h : (() => {
|
|
2662
|
+
let e = {};
|
|
2663
|
+
for (let n of t.variables) n.value !== null && (e[n.name] = n.value);
|
|
2664
|
+
return e;
|
|
2665
|
+
})(), v = g === null ? t.objectiveValue : g, y = {
|
|
2666
|
+
status: d,
|
|
2667
|
+
objectiveValue: v,
|
|
2668
|
+
lowerBound: f,
|
|
2669
|
+
upperBound: p,
|
|
2670
|
+
gap: m,
|
|
2671
|
+
iterations: u,
|
|
2672
|
+
cutsAdded: l,
|
|
2673
|
+
master: t,
|
|
2674
|
+
values: _
|
|
2675
|
+
};
|
|
2676
|
+
return t.decomposition = y, y;
|
|
2677
|
+
}
|
|
2678
|
+
//#endregion
|
|
2145
2679
|
//#region src/modeler/model.ts
|
|
2146
2680
|
function Z(e) {
|
|
2147
2681
|
return Array.isArray(e) || typeof e == "object" && !!e && !(e instanceof String) && typeof e[Symbol.iterator] == "function";
|
|
@@ -2149,10 +2683,13 @@ function Z(e) {
|
|
|
2149
2683
|
function Q(e) {
|
|
2150
2684
|
return typeof e == "object" && !!e && !Array.isArray(e) && !(e instanceof String) && typeof e[Symbol.iterator] != "function";
|
|
2151
2685
|
}
|
|
2686
|
+
function Xe(e) {
|
|
2687
|
+
return e instanceof M || typeof e == "object" && !!e && !(e instanceof u) && !(e instanceof y) && "id" in e && "name" in e && "lb" in e && "ub" in e && !("terms" in e) && !("quadTerms" in e) && !("sense" in e);
|
|
2688
|
+
}
|
|
2152
2689
|
function $(e, t) {
|
|
2153
2690
|
if (!Number.isInteger(e) || e < 0) throw Error(`Invalid count (${e}) for ${t} variable creation: count must be a non-negative integer.`);
|
|
2154
2691
|
}
|
|
2155
|
-
var
|
|
2692
|
+
var Ze = class {
|
|
2156
2693
|
name;
|
|
2157
2694
|
_sense;
|
|
2158
2695
|
_objectiveExpr;
|
|
@@ -2161,6 +2698,7 @@ var ze = class {
|
|
|
2161
2698
|
boolVars = [];
|
|
2162
2699
|
logicalConstraints = [];
|
|
2163
2700
|
unsatCore = void 0;
|
|
2701
|
+
_conflicts = void 0;
|
|
2164
2702
|
values = /* @__PURE__ */ new Map();
|
|
2165
2703
|
varMapByName = /* @__PURE__ */ new Map();
|
|
2166
2704
|
varPrefixCounters = /* @__PURE__ */ new Map();
|
|
@@ -2181,6 +2719,8 @@ var ze = class {
|
|
|
2181
2719
|
runTime = 0;
|
|
2182
2720
|
solution = null;
|
|
2183
2721
|
solver = null;
|
|
2722
|
+
decomposition;
|
|
2723
|
+
_linkingConstraints;
|
|
2184
2724
|
hasSolutionState = !1;
|
|
2185
2725
|
modelRevision = 0;
|
|
2186
2726
|
activeOperationId = 0;
|
|
@@ -2192,13 +2732,13 @@ var ze = class {
|
|
|
2192
2732
|
n = typeof e == "string" ? {
|
|
2193
2733
|
...t,
|
|
2194
2734
|
name: e
|
|
2195
|
-
} : e, this.name = n.name || "OptimizationModel", this._sense =
|
|
2735
|
+
} : e, this.name = n.name || "OptimizationModel", this._sense = s(n.sense), this._objectiveExpr = new C(), n.solver && (this.solver = V(n.solver));
|
|
2196
2736
|
}
|
|
2197
2737
|
get sense() {
|
|
2198
2738
|
return this._sense;
|
|
2199
2739
|
}
|
|
2200
2740
|
set sense(e) {
|
|
2201
|
-
let t =
|
|
2741
|
+
let t = s(e);
|
|
2202
2742
|
this._sense !== t && (this._sense = t, this.recordModelMutation());
|
|
2203
2743
|
}
|
|
2204
2744
|
get objectiveExpr() {
|
|
@@ -2208,7 +2748,10 @@ var ze = class {
|
|
|
2208
2748
|
this.applyObjective(e);
|
|
2209
2749
|
}
|
|
2210
2750
|
get conflicts() {
|
|
2211
|
-
return this.unsatCore;
|
|
2751
|
+
return this._conflicts ?? this.unsatCore;
|
|
2752
|
+
}
|
|
2753
|
+
set conflicts(e) {
|
|
2754
|
+
this._conflicts = e;
|
|
2212
2755
|
}
|
|
2213
2756
|
get numVars() {
|
|
2214
2757
|
return this.variables.length;
|
|
@@ -2218,7 +2761,7 @@ var ze = class {
|
|
|
2218
2761
|
}
|
|
2219
2762
|
clearSolutionFields() {
|
|
2220
2763
|
if (this.hasSolutionState || this.status !== "NotSolved" || this.terminationStatus !== "NotSolved" || this.hasPrimalSolution || this.solution !== null || this.unsatCore !== void 0) {
|
|
2221
|
-
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.values.clear();
|
|
2764
|
+
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();
|
|
2222
2765
|
for (let e of this.variables) e.value = null, e.reducedCost = null;
|
|
2223
2766
|
for (let e of this.boolVars) e.value = null;
|
|
2224
2767
|
for (let e of this.constraints) e.dual = null, e.slack = null;
|
|
@@ -2250,7 +2793,7 @@ var ze = class {
|
|
|
2250
2793
|
this.batchDepth = 0, this.batchMutated = !1;
|
|
2251
2794
|
for (let e = t; e < this.variables.length; e++) {
|
|
2252
2795
|
let t = this.variables[e];
|
|
2253
|
-
this.varMapByName.delete(t.name), t.ownerModel = null,
|
|
2796
|
+
this.varMapByName.delete(t.name), t.ownerModel = null, ne(t, this);
|
|
2254
2797
|
}
|
|
2255
2798
|
this.variables.length = t;
|
|
2256
2799
|
for (let e = n; e < this.boolVars.length; e++) {
|
|
@@ -2343,6 +2886,37 @@ var ze = class {
|
|
|
2343
2886
|
continuous(e, t, n) {
|
|
2344
2887
|
return this.createDomainVars("Continuous", e, t, n);
|
|
2345
2888
|
}
|
|
2889
|
+
addColumn(e) {
|
|
2890
|
+
let t = e.type || "Continuous", n = this.addVar({
|
|
2891
|
+
name: e.name,
|
|
2892
|
+
type: t,
|
|
2893
|
+
lb: e.lb,
|
|
2894
|
+
ub: e.ub
|
|
2895
|
+
});
|
|
2896
|
+
if (typeof e.cost == "number" && e.cost !== 0 && (this._objectiveExpr = this._objectiveExpr.add(n.mul(e.cost)), this.recordModelMutation()), e.coefficients) {
|
|
2897
|
+
if (Array.isArray(e.coefficients)) {
|
|
2898
|
+
for (let t of e.coefficients) if (Array.isArray(t)) {
|
|
2899
|
+
let [e, r] = t, i = typeof e == "string" ? this.getConstraintByName(e) : e;
|
|
2900
|
+
if (!i) throw Error(`Constraint '${String(e)}' not found in model when adding column`);
|
|
2901
|
+
i.addTerm(n, r);
|
|
2902
|
+
} else if (typeof t == "object" && t) {
|
|
2903
|
+
let e = typeof t.constraint == "string" ? this.getConstraintByName(t.constraint) : t.constraint;
|
|
2904
|
+
if (!e) throw Error(`Constraint '${String(t.constraint)}' not found in model when adding column`);
|
|
2905
|
+
e.addTerm(n, t.coeff);
|
|
2906
|
+
}
|
|
2907
|
+
} else if (e.coefficients instanceof Map) for (let [t, r] of e.coefficients.entries()) {
|
|
2908
|
+
let e = typeof t == "string" ? this.getConstraintByName(t) : t;
|
|
2909
|
+
if (!e) throw Error(`Constraint '${String(t)}' not found in model when adding column`);
|
|
2910
|
+
e.addTerm(n, r);
|
|
2911
|
+
}
|
|
2912
|
+
else if (typeof e.coefficients == "object") for (let [t, r] of Object.entries(e.coefficients)) {
|
|
2913
|
+
let e = this.getConstraintByName(t);
|
|
2914
|
+
if (!e) throw Error(`Constraint '${t}' not found in model when adding column`);
|
|
2915
|
+
e.addTerm(n, r);
|
|
2916
|
+
}
|
|
2917
|
+
}
|
|
2918
|
+
return n;
|
|
2919
|
+
}
|
|
2346
2920
|
bool(e, t, n) {
|
|
2347
2921
|
let r = typeof e == "number", i = typeof t == "number", a = Z(e), o = Z(t);
|
|
2348
2922
|
if (i || o) {
|
|
@@ -2418,19 +2992,19 @@ var ze = class {
|
|
|
2418
2992
|
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);
|
|
2419
2993
|
if (this.hasVarName(a)) throw Error(`Variable with name '${a}' already exists in model`);
|
|
2420
2994
|
if (this.hasConstraintName(a)) throw Error(`Boolean variable name '${a}' conflicts with an existing constraint in model`);
|
|
2421
|
-
let o = new
|
|
2995
|
+
let o = new d(a);
|
|
2422
2996
|
return this.boolVars.push(o), this.boolVarMapByName.set(o.name, o), this.recordModelMutation(), o;
|
|
2423
2997
|
}
|
|
2424
2998
|
addVar(e) {
|
|
2425
2999
|
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);
|
|
2426
3000
|
try {
|
|
2427
3001
|
if (this.hasVarName(s)) throw Error(`Variable with name '${s}' already exists in model`);
|
|
2428
|
-
let e = new
|
|
3002
|
+
let e = new M({
|
|
2429
3003
|
...t,
|
|
2430
3004
|
name: s,
|
|
2431
3005
|
prefix: a
|
|
2432
3006
|
});
|
|
2433
|
-
return e.hasExplicitName = r !== void 0, A(e),
|
|
3007
|
+
return e.hasExplicitName = r !== void 0, A(e), ee(e, this), e.ownerModel = this, this.variables.push(e), this.varMapByName.set(e.name, e), this.recordModelMutation(), e;
|
|
2434
3008
|
} catch (e) {
|
|
2435
3009
|
throw r === void 0 && (o === void 0 ? this.varPrefixCounters.delete(a) : this.varPrefixCounters.set(a, o)), e;
|
|
2436
3010
|
}
|
|
@@ -2448,37 +3022,42 @@ var ze = class {
|
|
|
2448
3022
|
return this.logicalConstrMapByName.get(e);
|
|
2449
3023
|
}
|
|
2450
3024
|
objective(e) {
|
|
2451
|
-
|
|
3025
|
+
if (arguments.length === 0) return this.objectiveExpr;
|
|
3026
|
+
let t = e;
|
|
3027
|
+
if (t instanceof y || 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}`)).");
|
|
3028
|
+
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}`)).");
|
|
3029
|
+
return this.applyObjective(t.expr, t.sense), this;
|
|
2452
3030
|
}
|
|
2453
3031
|
applyObjective(e, t) {
|
|
2454
|
-
if (e instanceof
|
|
2455
|
-
let n = t === void 0 ? this.sense :
|
|
2456
|
-
if (typeof e == "string") r =
|
|
2457
|
-
else if (typeof e == "number") r = new
|
|
2458
|
-
else if (e instanceof x) r = e.clone();
|
|
3032
|
+
if (e instanceof y || 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}`)).");
|
|
3033
|
+
let n = t === void 0 ? this.sense : s(t), r;
|
|
3034
|
+
if (typeof e == "string") r = me(e, (e) => this.getVarByName(e));
|
|
3035
|
+
else if (typeof e == "number") r = new C(/* @__PURE__ */ new Map(), e);
|
|
2459
3036
|
else if (e instanceof S) r = e.clone();
|
|
3037
|
+
else if (e instanceof C) r = e.clone();
|
|
2460
3038
|
else if (typeof e == "object" && e && "quadTerms" in e && e.quadTerms instanceof Map && "linearTerms" in e && e.linearTerms instanceof Map && typeof e.constant == "number") {
|
|
2461
3039
|
let t = e;
|
|
2462
|
-
r = new
|
|
3040
|
+
r = new S(t.linearTerms, t.quadTerms, t.constant);
|
|
2463
3041
|
} else if (typeof e == "object" && e && "terms" in e && e.terms instanceof Map && typeof e.constant == "number") {
|
|
2464
3042
|
let t = e;
|
|
2465
|
-
r = new
|
|
2466
|
-
} else if (e instanceof
|
|
3043
|
+
r = new C(t.terms, t.constant);
|
|
3044
|
+
} else if (e instanceof M || typeof e == "object" && e && "id" in e && "name" in e && "lb" in e && "ub" in e) r = new C(/* @__PURE__ */ new Map([[e, 1]]), 0);
|
|
2467
3045
|
else throw Error("Invalid objective expression: expected a finite number, Var, LinExpr, QuadExpr, or arithmetic expression string.");
|
|
2468
|
-
|
|
3046
|
+
oe(r, this.name, (e) => this.varMapByName.get(e.name) === e), this._sense = n, this._objectiveExpr = r, this.recordModelMutation();
|
|
2469
3047
|
}
|
|
2470
3048
|
constraint(e, t) {
|
|
2471
3049
|
if (Array.isArray(e)) return this.runTransactionalBatch(() => {
|
|
2472
3050
|
for (let t of e) this.constraint(t);
|
|
2473
3051
|
return this;
|
|
2474
3052
|
});
|
|
2475
|
-
if (e instanceof
|
|
2476
|
-
if (e instanceof
|
|
3053
|
+
if (e instanceof S || typeof e == "object" && e && "quadTerms" in e) throw Error("Constraint must contain a comparison operator (<=, >=, ==): cannot add a quadratic expression as a constraint.");
|
|
3054
|
+
if (e instanceof C || 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().");
|
|
3055
|
+
if (Xe(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().`);
|
|
2477
3056
|
return this.addConstraint(e, t), this;
|
|
2478
3057
|
}
|
|
2479
3058
|
getValues(e) {
|
|
2480
3059
|
if (e == null) return null;
|
|
2481
|
-
if (e instanceof
|
|
3060
|
+
if (e instanceof M || e instanceof d) return e.value;
|
|
2482
3061
|
if (Array.isArray(e)) return e.map((e) => this.getValues(e));
|
|
2483
3062
|
if (typeof e == "object") {
|
|
2484
3063
|
let t = {};
|
|
@@ -2488,9 +3067,10 @@ var ze = class {
|
|
|
2488
3067
|
return null;
|
|
2489
3068
|
}
|
|
2490
3069
|
addConstraint(e, t) {
|
|
2491
|
-
if (e instanceof
|
|
2492
|
-
if (e instanceof
|
|
2493
|
-
if (e
|
|
3070
|
+
if (e instanceof S || typeof e == "object" && e && "quadTerms" in e) throw Error("Constraint must contain a comparison operator (<=, >=, ==): cannot add a quadratic expression as a constraint.");
|
|
3071
|
+
if (e instanceof C || 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().");
|
|
3072
|
+
if (Xe(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().`);
|
|
3073
|
+
if (e instanceof u) {
|
|
2494
3074
|
let n = typeof t == "string" && t.trim().length > 0 ? t.trim() : void 0;
|
|
2495
3075
|
if (n !== void 0) {
|
|
2496
3076
|
if (this.hasConstraintName(n)) throw Error(`Constraint with name '${n}' already exists in model`);
|
|
@@ -2498,19 +3078,20 @@ var ze = class {
|
|
|
2498
3078
|
}
|
|
2499
3079
|
let r = this.logicalConstrCounter, i = n ?? this.getNextLogicalConstrName();
|
|
2500
3080
|
try {
|
|
2501
|
-
|
|
3081
|
+
se(e, i, this.name, (e) => this.varMapByName.get(e.name) === e, (e) => this.boolVarMapByName.get(e.name) === e, this);
|
|
2502
3082
|
} catch (e) {
|
|
2503
3083
|
throw n === void 0 && (this.logicalConstrCounter = r), e;
|
|
2504
3084
|
}
|
|
2505
|
-
|
|
3085
|
+
k(e, this, this.batchDepth > 0 ? this.batchUndoActions : void 0);
|
|
2506
3086
|
let a = {
|
|
2507
3087
|
name: i,
|
|
2508
3088
|
expr: e
|
|
2509
3089
|
};
|
|
2510
3090
|
return this.logicalConstraints.push(a), this.logicalConstrMapByName.set(i, a), this.recordModelMutation(), e;
|
|
2511
3091
|
}
|
|
2512
|
-
let n = typeof e == "string" ?
|
|
2513
|
-
n
|
|
3092
|
+
let n = typeof e == "string" ? ge(e, (e) => this.getVarByName(e), t) : e;
|
|
3093
|
+
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.");
|
|
3094
|
+
n.ownerModel && n.ownerModel !== this && (j(n, this.name, (e) => this.varMapByName.get(e.name) === e, n.name), te(n, this));
|
|
2514
3095
|
let r = typeof t == "string" && t.trim().length > 0 ? t.trim() : n.hasExplicitName ? n.name.trim() : void 0;
|
|
2515
3096
|
if (r !== void 0) {
|
|
2516
3097
|
if (this.hasConstraintName(r)) throw Error(`Constraint with name '${r}' already exists in model`);
|
|
@@ -2518,54 +3099,55 @@ var ze = class {
|
|
|
2518
3099
|
}
|
|
2519
3100
|
let i = this.constrPrefixCounters.get("c"), a = r ?? this.getNextConstrName("c"), o;
|
|
2520
3101
|
try {
|
|
2521
|
-
j(n, this.name, (e) => this.varMapByName.get(e.name) === e, a), o =
|
|
3102
|
+
j(n, this.name, (e) => this.varMapByName.get(e.name) === e, a), o = te(n, this);
|
|
2522
3103
|
} catch (e) {
|
|
2523
3104
|
throw r === void 0 && (i === void 0 ? this.constrPrefixCounters.delete("c") : this.constrPrefixCounters.set("c", i)), e;
|
|
2524
3105
|
}
|
|
2525
|
-
let s = n.name, c = n.hasExplicitName,
|
|
3106
|
+
let s = n.name, c = n.hasExplicitName, l = n.ownerModel, d = o;
|
|
2526
3107
|
return this.batchUndoActions.push(() => {
|
|
2527
|
-
n.ownerModel =
|
|
3108
|
+
n.ownerModel = l, n._assignModelName(s, c), re(n, this, d);
|
|
2528
3109
|
}), this.batchDepth === 0 && (this.batchUndoActions = []), n._assignModelName(a, !0), n.ownerModel = this, this.constraints.push(n), this.constrMapByName.set(n.name, n), this.recordModelMutation(), n;
|
|
2529
3110
|
}
|
|
2530
3111
|
indicator(e, t, n = {}) {
|
|
2531
|
-
if (
|
|
2532
|
-
if (!(e
|
|
2533
|
-
if (
|
|
2534
|
-
if (
|
|
3112
|
+
if (e instanceof u) 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.");
|
|
3113
|
+
if (!(e instanceof M)) 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).");
|
|
3114
|
+
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]).`);
|
|
3115
|
+
if (t instanceof S || 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).");
|
|
3116
|
+
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.");
|
|
2535
3117
|
let r = t, i = n.activeValue === void 0 ? 1 : n.activeValue;
|
|
2536
3118
|
if (i !== 0 && i !== 1) throw Error(`Invalid activeValue: ${i}. Indicator activeValue must be 0 or 1.`);
|
|
2537
3119
|
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.`);
|
|
2538
|
-
let a = typeof n.name == "string" && n.name.trim().length > 0 ? n.name.trim() : void 0, o = this.constrPrefixCounters.get("c"), { lhs: s, sense: c, rhs: l } = r,
|
|
2539
|
-
if (a !== void 0)
|
|
2540
|
-
else if (r.hasExplicitName)
|
|
3120
|
+
let a = typeof n.name == "string" && n.name.trim().length > 0 ? n.name.trim() : void 0, o = this.constrPrefixCounters.get("c"), { lhs: s, sense: c, rhs: l } = r, d, f, p;
|
|
3121
|
+
if (a !== void 0) d = a, f = c === "==" ? `${d}_le` : d, p = c === "==" ? `${d}_ge` : d;
|
|
3122
|
+
else if (r.hasExplicitName) d = `ind_${e.name}_${r.name.trim()}`, f = c === "==" ? `${d}_le` : d, p = c === "==" ? `${d}_ge` : d;
|
|
2541
3123
|
else do {
|
|
2542
3124
|
let t = this.getNextConstrName("c");
|
|
2543
|
-
|
|
2544
|
-
} while ((c === "<=" || c === "==") && (this.hasConstraintName(
|
|
2545
|
-
let
|
|
3125
|
+
d = `ind_${e.name}_${t}`, f = c === "==" ? `${d}_le` : d, p = c === "==" ? `${d}_ge` : d;
|
|
3126
|
+
} while ((c === "<=" || c === "==") && (this.hasConstraintName(f) || this.hasBoolVarName(f)) || (c === ">=" || c === "==") && (this.hasConstraintName(p) || this.hasBoolVarName(p)));
|
|
3127
|
+
let m = [];
|
|
2546
3128
|
try {
|
|
2547
|
-
if ((c === "<=" || c === "==") && (this.hasConstraintName(
|
|
2548
|
-
if ((c === ">=" || c === "==") && (this.hasConstraintName(
|
|
2549
|
-
n.M !== void 0 &&
|
|
3129
|
+
if ((c === "<=" || c === "==") && (this.hasConstraintName(f) || this.hasBoolVarName(f))) throw Error(this.hasBoolVarName(f) ? `Constraint name '${f}' conflicts with an existing Boolean variable in model` : `Constraint with name '${f}' already exists in model`);
|
|
3130
|
+
if ((c === ">=" || c === "==") && (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`);
|
|
3131
|
+
n.M !== void 0 && ze(n.M, d);
|
|
2550
3132
|
let t = (e) => this.varMapByName.get(e.name) === e;
|
|
2551
|
-
for (let [e] of s.terms) if (!t(e)) throw Error(`Variable "${e.name}" in constraint "${
|
|
3133
|
+
for (let [e] of s.terms) if (!t(e)) throw Error(`Variable "${e.name}" in constraint "${d}" does not belong to model "${this.name}". All variables must belong to the model by object identity.`);
|
|
2552
3134
|
if (c === "<=" || c === "==") {
|
|
2553
|
-
let t =
|
|
2554
|
-
|
|
3135
|
+
let t = Y(e, s, "<=", l, i, n.M === void 0 ? q(s, l, f) : n.M, f);
|
|
3136
|
+
m.push([new y(t.lhs, "<=", t.rhs, f), f]);
|
|
2555
3137
|
}
|
|
2556
3138
|
if (c === ">=" || c === "==") {
|
|
2557
|
-
let t =
|
|
2558
|
-
|
|
3139
|
+
let t = Y(e, s, ">=", l, i, n.M === void 0 ? J(s, l, p) : n.M, p);
|
|
3140
|
+
m.push([new y(t.lhs, ">=", t.rhs, p), p]);
|
|
2559
3141
|
}
|
|
2560
|
-
for (let [e, n] of
|
|
3142
|
+
for (let [e, n] of m) j(e, this.name, t, n);
|
|
2561
3143
|
} catch (e) {
|
|
2562
3144
|
throw o === void 0 ? this.constrPrefixCounters.delete("c") : this.constrPrefixCounters.set("c", o), e;
|
|
2563
3145
|
}
|
|
2564
|
-
return this.runTransactionalBatch(() =>
|
|
3146
|
+
return this.runTransactionalBatch(() => m.map(([e, t]) => this.addConstraint(e, t)));
|
|
2565
3147
|
}
|
|
2566
3148
|
toLpString() {
|
|
2567
3149
|
this.validateIntegrity();
|
|
2568
|
-
let { lpString: e } =
|
|
3150
|
+
let { lpString: e } = L({
|
|
2569
3151
|
name: this.name,
|
|
2570
3152
|
sense: this.sense,
|
|
2571
3153
|
objective: this.objectiveExpr,
|
|
@@ -2575,7 +3157,7 @@ var ze = class {
|
|
|
2575
3157
|
return e;
|
|
2576
3158
|
}
|
|
2577
3159
|
validateIntegrity() {
|
|
2578
|
-
|
|
3160
|
+
ce(this);
|
|
2579
3161
|
}
|
|
2580
3162
|
ensureExecutionValid(e, t, n) {
|
|
2581
3163
|
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.`);
|
|
@@ -2613,27 +3195,44 @@ var ze = class {
|
|
|
2613
3195
|
if (typeof e == "string") {
|
|
2614
3196
|
let { solver: n, ...r } = t || {};
|
|
2615
3197
|
return {
|
|
2616
|
-
activeSolver:
|
|
3198
|
+
activeSolver: V(e, r),
|
|
2617
3199
|
activeOptions: r
|
|
2618
3200
|
};
|
|
2619
3201
|
}
|
|
2620
3202
|
let { solver: n, ...r } = e || {};
|
|
2621
3203
|
return n ? {
|
|
2622
|
-
activeSolver:
|
|
3204
|
+
activeSolver: V(n, r),
|
|
2623
3205
|
activeOptions: r
|
|
2624
3206
|
} : {
|
|
2625
|
-
activeSolver: this.solver ||
|
|
3207
|
+
activeSolver: this.solver || V(),
|
|
2626
3208
|
activeOptions: r
|
|
2627
3209
|
};
|
|
2628
3210
|
}
|
|
3211
|
+
async relax(e, t) {
|
|
3212
|
+
let n = typeof e == "object" && !!e && !("solve" in e), r = n ? {
|
|
3213
|
+
...e,
|
|
3214
|
+
relax: !0
|
|
3215
|
+
} : {
|
|
3216
|
+
...t || {},
|
|
3217
|
+
relax: !0
|
|
3218
|
+
}, i = n ? void 0 : e;
|
|
3219
|
+
return i ? this.solve(i, r) : this.solve(r);
|
|
3220
|
+
}
|
|
2629
3221
|
async solve(e, t) {
|
|
2630
3222
|
let n = ++this.activeOperationId, r = this.modelRevision;
|
|
2631
3223
|
this.clearSolutionFields(), this.validateIntegrity();
|
|
2632
3224
|
let { activeSolver: i, activeOptions: a } = this.resolveSolverAndOptions(e, t);
|
|
2633
|
-
if (this._objectiveExpr instanceof
|
|
2634
|
-
|
|
2635
|
-
if (this.
|
|
2636
|
-
|
|
3225
|
+
if (this._objectiveExpr instanceof S && 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.`);
|
|
3226
|
+
let o, s = null;
|
|
3227
|
+
if (this.logicalConstraints.length > 0 && i.capabilities?.supportsSMT !== !0 ? (s = Ve(this.variables, this.boolVars, this.constraints, this.logicalConstraints), o = {
|
|
3228
|
+
name: this.name,
|
|
3229
|
+
sense: this.sense,
|
|
3230
|
+
objective: this._objectiveExpr,
|
|
3231
|
+
constraints: s.constraints,
|
|
3232
|
+
variables: s.variables,
|
|
3233
|
+
logicalConstraints: [],
|
|
3234
|
+
boolVars: []
|
|
3235
|
+
}) : o = {
|
|
2637
3236
|
name: this.name,
|
|
2638
3237
|
sense: this.sense,
|
|
2639
3238
|
objective: this._objectiveExpr,
|
|
@@ -2641,53 +3240,64 @@ var ze = class {
|
|
|
2641
3240
|
variables: this.variables,
|
|
2642
3241
|
logicalConstraints: this.logicalConstraints,
|
|
2643
3242
|
boolVars: this.boolVars
|
|
2644
|
-
},
|
|
3243
|
+
}, 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.`);
|
|
3244
|
+
let c = this.wrapSolveOptions(a, r, n), l;
|
|
2645
3245
|
try {
|
|
2646
|
-
|
|
3246
|
+
l = await i.solve(o, c);
|
|
2647
3247
|
} catch (e) {
|
|
2648
3248
|
throw this.activeOperationId === n && this.clearSolutionFields(), e;
|
|
2649
3249
|
}
|
|
2650
|
-
this.ensureExecutionValid(r, n, "solve"), this.runTime =
|
|
2651
|
-
let
|
|
2652
|
-
this.hasPrimalSolution =
|
|
2653
|
-
let
|
|
2654
|
-
this.relGap =
|
|
2655
|
-
let
|
|
3250
|
+
this.ensureExecutionValid(r, n, "solve"), this.runTime = l.runTime ?? 0, this.status = l.status, this.terminationStatus = l.terminationStatus ?? l.status;
|
|
3251
|
+
let u = this.hasPrimalFromResult(l);
|
|
3252
|
+
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;
|
|
3253
|
+
let d = typeof l.relGap == "number" && Number.isFinite(l.relGap) ? l.relGap : typeof l.mipGap == "number" && Number.isFinite(l.mipGap) ? l.mipGap : void 0;
|
|
3254
|
+
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;
|
|
3255
|
+
let f = (e, t, n) => {
|
|
2656
3256
|
Object.defineProperty(e, t, {
|
|
2657
3257
|
value: n,
|
|
2658
3258
|
enumerable: !0,
|
|
2659
3259
|
writable: !0,
|
|
2660
3260
|
configurable: !0
|
|
2661
3261
|
});
|
|
2662
|
-
},
|
|
2663
|
-
if (this.values.clear(),
|
|
2664
|
-
for (let [e, t] of Object.entries(
|
|
3262
|
+
}, p = {}, m = {}, h = {}, g = {};
|
|
3263
|
+
if (this.values.clear(), u && l.values) {
|
|
3264
|
+
for (let [e, t] of Object.entries(l.values)) if (typeof t == "number" && Number.isFinite(t)) {
|
|
2665
3265
|
let n = this.getVarByName(e), r = this.getBoolVarByName(e);
|
|
2666
|
-
n && (n.value = t,
|
|
3266
|
+
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);
|
|
2667
3267
|
} else if (typeof t == "boolean") {
|
|
2668
3268
|
let n = t, r = this.getBoolVarByName(e);
|
|
2669
|
-
r ? (r.value = n,
|
|
3269
|
+
r ? (r.value = n, f(p, r.name, +!!n), this.values.set(r.name, n)) : this.values.set(e, n);
|
|
3270
|
+
}
|
|
3271
|
+
if (s) for (let e of this.boolVars) {
|
|
3272
|
+
let t = s.boolVarToBinary.get(e);
|
|
3273
|
+
if (t && l.values) {
|
|
3274
|
+
let n = l.values[t.name];
|
|
3275
|
+
if (typeof n == "number" && Number.isFinite(n)) {
|
|
3276
|
+
let t = Math.round(n) === 1;
|
|
3277
|
+
e.value = t, f(p, e.name, +!!t), this.values.set(e.name, t);
|
|
3278
|
+
}
|
|
3279
|
+
}
|
|
2670
3280
|
}
|
|
2671
3281
|
}
|
|
2672
|
-
if (
|
|
3282
|
+
if (u && l.boolValues) for (let [e, t] of Object.entries(l.boolValues)) {
|
|
2673
3283
|
if (typeof t != "boolean") continue;
|
|
2674
3284
|
let n = this.getBoolVarByName(e);
|
|
2675
3285
|
n ? (n.value = t, this.values.has(n.name) || this.values.set(n.name, t)) : this.values.has(e) || this.values.set(e, t);
|
|
2676
3286
|
}
|
|
2677
|
-
if (
|
|
3287
|
+
if (u && l.reducedCosts) for (let [e, t] of Object.entries(l.reducedCosts)) {
|
|
2678
3288
|
if (typeof t != "number" || !Number.isFinite(t)) continue;
|
|
2679
3289
|
let n = this.getVarByName(e);
|
|
2680
|
-
n && (n.reducedCost = t,
|
|
3290
|
+
n && (n.reducedCost = t, f(h, n.name, t));
|
|
2681
3291
|
}
|
|
2682
|
-
if (
|
|
3292
|
+
if (l.duals) for (let [e, t] of Object.entries(l.duals)) {
|
|
2683
3293
|
if (typeof t != "number" || !Number.isFinite(t)) continue;
|
|
2684
3294
|
let n = this.getConstraintByName(e);
|
|
2685
|
-
n && (n.dual = t,
|
|
3295
|
+
n && (n.dual = t, f(m, n.name, t));
|
|
2686
3296
|
}
|
|
2687
|
-
if (
|
|
3297
|
+
if (l.slacks) for (let [e, t] of Object.entries(l.slacks)) {
|
|
2688
3298
|
if (typeof t != "number" || !Number.isFinite(t)) continue;
|
|
2689
3299
|
let n = this.getConstraintByName(e);
|
|
2690
|
-
n && (n.slack = t,
|
|
3300
|
+
n && (n.slack = t, f(g, n.name, t));
|
|
2691
3301
|
}
|
|
2692
3302
|
return this.solution = {
|
|
2693
3303
|
status: this.status,
|
|
@@ -2700,19 +3310,18 @@ var ze = class {
|
|
|
2700
3310
|
mipGap: this.mipGap
|
|
2701
3311
|
},
|
|
2702
3312
|
...this.absGap === void 0 ? {} : { absGap: this.absGap },
|
|
2703
|
-
values:
|
|
2704
|
-
duals:
|
|
2705
|
-
reducedCosts:
|
|
2706
|
-
slacks:
|
|
3313
|
+
values: p,
|
|
3314
|
+
duals: m,
|
|
3315
|
+
reducedCosts: h,
|
|
3316
|
+
slacks: g,
|
|
2707
3317
|
runTime: this.runTime,
|
|
2708
|
-
raw:
|
|
3318
|
+
raw: l.raw
|
|
2709
3319
|
}, this.hasSolutionState = !0, this.status;
|
|
2710
3320
|
}
|
|
2711
3321
|
async check(e, t) {
|
|
2712
3322
|
let n = ++this.activeOperationId, r = this.modelRevision;
|
|
2713
3323
|
this.clearSolutionFields(), this.validateIntegrity();
|
|
2714
3324
|
let { activeSolver: i, activeOptions: a } = this.resolveSolverAndOptions(e, t);
|
|
2715
|
-
if (this.logicalConstraints.length > 0 && i.capabilities?.supportsSMT !== !0) throw Error(`Solver "${i.name}" does not support SMT / logical constraints (or, implies, not, xor). Please use an SMT-capable solver such as Z3.`);
|
|
2716
3325
|
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.`);
|
|
2717
3326
|
let o = this.wrapSolveOptions(a, r, n), s = (e, t, n) => {
|
|
2718
3327
|
Object.defineProperty(e, t, {
|
|
@@ -2735,7 +3344,7 @@ var ze = class {
|
|
|
2735
3344
|
} catch (e) {
|
|
2736
3345
|
throw this.activeOperationId === n && this.clearSolutionFields(), e;
|
|
2737
3346
|
}
|
|
2738
|
-
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]);
|
|
3347
|
+
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]);
|
|
2739
3348
|
let t = {};
|
|
2740
3349
|
if (e.values && e.status === "Sat") {
|
|
2741
3350
|
for (let [n, r] of Object.entries(e.values)) if (typeof r == "number") {
|
|
@@ -2751,81 +3360,124 @@ var ze = class {
|
|
|
2751
3360
|
status: e.status,
|
|
2752
3361
|
values: t,
|
|
2753
3362
|
unsatCore: this.unsatCore,
|
|
2754
|
-
conflicts: this.
|
|
3363
|
+
conflicts: this.conflicts,
|
|
2755
3364
|
runTime: this.runTime
|
|
2756
3365
|
};
|
|
2757
3366
|
}
|
|
2758
|
-
let l = {
|
|
2759
|
-
|
|
3367
|
+
let l = this.logicalConstraints.length > 0 || this.boolVars.length > 0 ? Ve(this.variables, this.boolVars, this.constraints, this.logicalConstraints) : {
|
|
3368
|
+
variables: [...this.variables],
|
|
3369
|
+
constraints: [...this.constraints],
|
|
3370
|
+
boolVarToBinary: /* @__PURE__ */ new Map(),
|
|
3371
|
+
constraintToOriginalName: new Map(this.constraints.map((e) => [e, e.name]))
|
|
3372
|
+
}, u = [], d = [], f = [], p = /* @__PURE__ */ new Map(), m = 0;
|
|
3373
|
+
for (let e of l.constraints) {
|
|
3374
|
+
let t = l.constraintToOriginalName.get(e) ?? e.name, { lhs: n, sense: r, rhs: i } = e;
|
|
3375
|
+
if (r === "<=") {
|
|
3376
|
+
let r = new M({
|
|
3377
|
+
name: `__slack_${++m}`,
|
|
3378
|
+
type: "Continuous",
|
|
3379
|
+
lb: 0,
|
|
3380
|
+
ub: Infinity
|
|
3381
|
+
});
|
|
3382
|
+
d.push(r), f.push([r, 1]), p.set(r, t);
|
|
3383
|
+
let a = n.clone().add(new C(/* @__PURE__ */ new Map([[r, -1]]), 0));
|
|
3384
|
+
u.push(new y(a, "<=", i, `${e.name}_slack`));
|
|
3385
|
+
} else if (r === ">=") {
|
|
3386
|
+
let r = new M({
|
|
3387
|
+
name: `__slack_${++m}`,
|
|
3388
|
+
type: "Continuous",
|
|
3389
|
+
lb: 0,
|
|
3390
|
+
ub: Infinity
|
|
3391
|
+
});
|
|
3392
|
+
d.push(r), f.push([r, 1]), p.set(r, t);
|
|
3393
|
+
let a = n.clone().add(new C(/* @__PURE__ */ new Map([[r, 1]]), 0));
|
|
3394
|
+
u.push(new y(a, ">=", i, `${e.name}_slack`));
|
|
3395
|
+
} else {
|
|
3396
|
+
let r = new M({
|
|
3397
|
+
name: `__slack_${++m}_p`,
|
|
3398
|
+
type: "Continuous",
|
|
3399
|
+
lb: 0,
|
|
3400
|
+
ub: Infinity
|
|
3401
|
+
}), a = new M({
|
|
3402
|
+
name: `__slack_${++m}_n`,
|
|
3403
|
+
type: "Continuous",
|
|
3404
|
+
lb: 0,
|
|
3405
|
+
ub: Infinity
|
|
3406
|
+
});
|
|
3407
|
+
d.push(r, a), f.push([r, 1], [a, 1]), p.set(r, t), p.set(a, t);
|
|
3408
|
+
let o = n.clone().add(new C(/* @__PURE__ */ new Map([[r, -1], [a, 1]]), 0));
|
|
3409
|
+
u.push(new y(o, "==", i, `${e.name}_slack`));
|
|
3410
|
+
}
|
|
3411
|
+
}
|
|
3412
|
+
let h = {
|
|
3413
|
+
name: `${this.name}_elastic_check`,
|
|
2760
3414
|
sense: "Minimize",
|
|
2761
|
-
objective: new
|
|
2762
|
-
constraints:
|
|
2763
|
-
variables:
|
|
2764
|
-
|
|
2765
|
-
boolVars: this.boolVars
|
|
2766
|
-
}, u;
|
|
3415
|
+
objective: new C(new Map(f), 0),
|
|
3416
|
+
constraints: u,
|
|
3417
|
+
variables: [...l.variables, ...d]
|
|
3418
|
+
}, g;
|
|
2767
3419
|
try {
|
|
2768
|
-
|
|
3420
|
+
g = await i.solve(h, o);
|
|
2769
3421
|
} catch (e) {
|
|
2770
3422
|
throw this.activeOperationId === n && this.clearSolutionFields(), e;
|
|
2771
3423
|
}
|
|
2772
|
-
this.ensureExecutionValid(r, n, "check"), this.runTime =
|
|
2773
|
-
let
|
|
2774
|
-
this.status =
|
|
2775
|
-
let
|
|
2776
|
-
if (
|
|
2777
|
-
for (let
|
|
2778
|
-
let
|
|
2779
|
-
|
|
2780
|
-
}
|
|
2781
|
-
|
|
2782
|
-
|
|
3424
|
+
this.ensureExecutionValid(r, n, "check"), this.runTime = g.runTime ?? 0;
|
|
3425
|
+
let _ = g.status, v = g.terminationStatus ?? _, b = this.hasPrimalFromResult(g), x = typeof g.objectiveValue == "number" && Number.isFinite(g.objectiveValue) ? g.objectiveValue : Infinity, S = (_ === "Optimal" || _ === "Feasible" || b) && x <= 1e-5, w = typeof g.objectiveBound == "number" && Number.isFinite(g.objectiveBound) && g.objectiveBound > 1e-5, T = !S && (_ === "Infeasible" || _ === "Optimal" && x > 1e-5 || w), E = S ? "Sat" : T ? "Unsat" : "Unknown";
|
|
3426
|
+
this.status = E, this.terminationStatus = a.signal?.aborted || v === "Interrupted" ? "Interrupted" : v === "Optimal" || v === "Feasible" || v === "Infeasible" ? E : v, this.hasPrimalSolution = S, 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();
|
|
3427
|
+
let D = {};
|
|
3428
|
+
if (S && g.values) {
|
|
3429
|
+
for (let e of this.variables) {
|
|
3430
|
+
let t = g.values[e.name];
|
|
3431
|
+
typeof t == "number" && Number.isFinite(t) && (e.value = t, this.values.set(e.name, t), s(D, e.name, t));
|
|
3432
|
+
}
|
|
3433
|
+
for (let e of this.boolVars) {
|
|
3434
|
+
let t = l.boolVarToBinary.get(e), n = t ? g.values[t.name] : g.values[e.name];
|
|
3435
|
+
if (typeof n == "number" && Number.isFinite(n)) {
|
|
3436
|
+
let t = Math.round(n) === 1;
|
|
3437
|
+
e.value = t, this.values.set(e.name, t), s(D, e.name, t);
|
|
3438
|
+
}
|
|
2783
3439
|
}
|
|
2784
3440
|
}
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
let n =
|
|
2788
|
-
n
|
|
2789
|
-
}
|
|
2790
|
-
if (u.slacks) for (let [e, t] of Object.entries(u.slacks)) {
|
|
2791
|
-
if (typeof t != "number" || !Number.isFinite(t)) continue;
|
|
2792
|
-
let n = this.getConstraintByName(e);
|
|
2793
|
-
n && (n.slack = t);
|
|
3441
|
+
let O = /* @__PURE__ */ new Set();
|
|
3442
|
+
if (T && g.values) for (let [e, t] of p.entries()) {
|
|
3443
|
+
let n = g.values[e.name];
|
|
3444
|
+
typeof n == "number" && n > 1e-5 && O.add(t);
|
|
2794
3445
|
}
|
|
2795
|
-
return this.hasSolutionState = !0, {
|
|
2796
|
-
status:
|
|
2797
|
-
values:
|
|
3446
|
+
return this.conflicts = T ? Object.freeze(Array.from(O)) : void 0, this.unsatCore = void 0, this.hasSolutionState = !0, {
|
|
3447
|
+
status: E,
|
|
3448
|
+
values: D,
|
|
3449
|
+
conflicts: this.conflicts,
|
|
3450
|
+
unsatCore: this.unsatCore,
|
|
2798
3451
|
runTime: this.runTime
|
|
2799
3452
|
};
|
|
2800
3453
|
}
|
|
2801
3454
|
validateSolution(e = {}) {
|
|
2802
|
-
return
|
|
3455
|
+
return Re(this, e);
|
|
3456
|
+
}
|
|
3457
|
+
link(e) {
|
|
3458
|
+
if (e instanceof S || typeof e == "object" && e && "quadTerms" in e) throw Error("Linking constraint cannot be a quadratic expression.");
|
|
3459
|
+
if (!(e instanceof y) && (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().");
|
|
3460
|
+
this._linkingConstraints ||= [];
|
|
3461
|
+
let t = e;
|
|
3462
|
+
return this._linkingConstraints.push(t), t;
|
|
3463
|
+
}
|
|
3464
|
+
get linkingConstraints() {
|
|
3465
|
+
return this._linkingConstraints ?? [];
|
|
3466
|
+
}
|
|
3467
|
+
async solveBenders(e) {
|
|
3468
|
+
let t = await Ye({
|
|
3469
|
+
master: this,
|
|
3470
|
+
...e
|
|
3471
|
+
});
|
|
3472
|
+
return this.decomposition = t, t;
|
|
2803
3473
|
}
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
if (typeof n == "string" && /(<=|>=|==|=<|=>|=)/.test(n)) throw Error(`Cannot use a comparison constraint as an objective in ${t}(). Use model.constraint(expr\`... <= ...\`) for constraints, or supply an unconstrained arithmetic expression to ${t}().`);
|
|
2811
|
-
if (typeof n == "number") {
|
|
2812
|
-
if (!Number.isFinite(n)) throw Error(`Invalid non-finite objective constant "${n}" passed to ${t}().`);
|
|
2813
|
-
return n;
|
|
3474
|
+
async solveColumnGeneration(e) {
|
|
3475
|
+
let t = await Ue({
|
|
3476
|
+
master: this,
|
|
3477
|
+
...e
|
|
3478
|
+
});
|
|
3479
|
+
return this.decomposition = t, t;
|
|
2814
3480
|
}
|
|
2815
|
-
|
|
2816
|
-
throw Error(`Invalid expression passed to ${t}(): expected a finite number, Var, LinExpr, QuadExpr, or arithmetic expression string.`);
|
|
2817
|
-
}
|
|
2818
|
-
function Ve(e) {
|
|
2819
|
-
return {
|
|
2820
|
-
expr: Be(e, "maximize"),
|
|
2821
|
-
sense: "Maximize"
|
|
2822
|
-
};
|
|
2823
|
-
}
|
|
2824
|
-
function He(e) {
|
|
2825
|
-
return {
|
|
2826
|
-
expr: Be(e, "minimize"),
|
|
2827
|
-
sense: "Minimize"
|
|
2828
|
-
};
|
|
2829
|
-
}
|
|
3481
|
+
};
|
|
2830
3482
|
//#endregion
|
|
2831
|
-
export {
|
|
3483
|
+
export { u as BoolExpr, f as BoolOp, d as BoolVar, y as Constraint, Ne as HiGHS, r as Highs, K as HighsSolver, C as LinExpr, Fe as MockSolver, Ze as Model, S as QuadExpr, M as Var, p as and, Y as buildIndicatorLinearization, xe as buildLpSymbolMaps, J as deriveBigMForGe, q as deriveBigMForLe, T as dot, be as expr, L as generateLpString, o as getHighs, n as getHighsWasmUrl, V as getSolver, g as implies, F as isLpExportResult, Ve as linearizeModelForMip, H as listAvailableSolvers, Ge as maximize, Ke as minimize, s as normalizeSense, h as not, m as or, ge as parseConstraint, me as parseExpr, Ce as registerSolver, I as sanitizeIdentifier, we as setDefaultSolver, t as setHighsWasmUrl, Ye as solveBenders, Ue as solveColumnGeneration, e as solveLpWithHighs, w as sum, ce as validateModelIntegrity, Re as validateModelSolution, ze as validateUserBigM, _ as xor };
|