@ohtaman/washi 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +149 -121
- package/README.md +149 -121
- package/README.zh-CN.md +150 -122
- package/THIRD_PARTY_LICENSES.md +3 -4
- package/dist/browser/_washi-node-only-BvRk9kiK.js +0 -0
- package/dist/browser/browser-runtime-TLCY0hkc.js +1793 -0
- package/dist/browser/highs-worker.js +21 -3
- package/dist/browser/highs.wasm +0 -0
- package/dist/browser/highs.wasm.LICENSE +1 -2
- package/dist/browser/loader-DewlSho8.js +643 -0
- package/dist/browser/solvers/glpk.js +433 -286
- package/dist/browser/solvers/glpk.min.js +1 -1
- package/dist/browser/solvers/z3.js +1008 -981
- package/dist/browser/solvers/z3.min.js +2 -2
- package/dist/browser/washi.js +2778 -673
- package/dist/browser/washi.min.js +3 -4
- package/dist/lib/_washi-node-only-BvRk9kiK.js +0 -0
- package/dist/lib/highs-browser-runtime.js +2120 -4124
- package/dist/lib/highs-node-runtime.js +24 -1
- package/dist/lib/highs-runtime.js +2 -0
- package/dist/lib/highs-worker.js +21 -3
- package/dist/lib/highs.wasm +0 -0
- package/dist/lib/highs.wasm.LICENSE +1 -2
- package/dist/lib/loader-BZUQNvh4.js +649 -0
- package/dist/lib/registry-C20sxTwm.js +964 -0
- package/dist/lib/solvers/glpk.js +201 -90
- package/dist/lib/solvers/z3.js +399 -259
- package/dist/lib/washi.js +2363 -1056
- package/dist/types/decomposition/benders.d.ts +32 -0
- package/dist/types/decomposition/benders.d.ts.map +1 -0
- package/dist/types/decomposition/column-generation.d.ts +34 -0
- package/dist/types/decomposition/column-generation.d.ts.map +1 -0
- package/dist/types/decomposition/index.d.ts +4 -0
- package/dist/types/decomposition/index.d.ts.map +1 -0
- package/dist/types/decomposition/types.d.ts +230 -0
- package/dist/types/decomposition/types.d.ts.map +1 -0
- package/dist/types/index.d.ts +5 -4
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/modeler/big-m.d.ts +75 -0
- package/dist/types/modeler/big-m.d.ts.map +1 -0
- package/dist/types/modeler/boolean-expr.d.ts +103 -14
- package/dist/types/modeler/boolean-expr.d.ts.map +1 -1
- package/dist/types/modeler/constraint.d.ts +47 -9
- package/dist/types/modeler/constraint.d.ts.map +1 -1
- package/dist/types/modeler/expression.d.ts +123 -28
- package/dist/types/modeler/expression.d.ts.map +1 -1
- package/dist/types/modeler/index.d.ts +11 -6
- package/dist/types/modeler/index.d.ts.map +1 -1
- package/dist/types/modeler/linearizer.d.ts +15 -0
- package/dist/types/modeler/linearizer.d.ts.map +1 -0
- package/dist/types/modeler/lp-writer.d.ts +30 -3
- package/dist/types/modeler/lp-writer.d.ts.map +1 -1
- package/dist/types/modeler/model.d.ts +623 -131
- package/dist/types/modeler/model.d.ts.map +1 -1
- package/dist/types/modeler/objective.d.ts +59 -0
- package/dist/types/modeler/objective.d.ts.map +1 -0
- package/dist/types/modeler/parser.d.ts +34 -10
- package/dist/types/modeler/parser.d.ts.map +1 -1
- package/dist/types/modeler/quad-expr.d.ts +26 -7
- package/dist/types/modeler/quad-expr.d.ts.map +1 -1
- package/dist/types/modeler/solution-validator.d.ts +93 -0
- package/dist/types/modeler/solution-validator.d.ts.map +1 -0
- package/dist/types/modeler/solvers/glpk/solver.d.ts +26 -2
- package/dist/types/modeler/solvers/glpk/solver.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/browser-runtime.d.ts +2 -1
- package/dist/types/modeler/solvers/highs/browser-runtime.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/driver.d.ts +232 -0
- package/dist/types/modeler/solvers/highs/driver.d.ts.map +1 -0
- package/dist/types/modeler/solvers/highs/index.d.ts +1 -0
- package/dist/types/modeler/solvers/highs/index.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/loader.d.ts +38 -13
- package/dist/types/modeler/solvers/highs/loader.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/node-runtime.d.ts +2 -1
- package/dist/types/modeler/solvers/highs/node-runtime.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/solver.d.ts +12 -5
- package/dist/types/modeler/solvers/highs/solver.d.ts.map +1 -1
- package/dist/types/modeler/solvers/highs/worker-client.d.ts.map +1 -1
- package/dist/types/modeler/solvers/mock.d.ts +14 -5
- package/dist/types/modeler/solvers/mock.d.ts.map +1 -1
- package/dist/types/modeler/solvers/types.d.ts +73 -11
- package/dist/types/modeler/solvers/types.d.ts.map +1 -1
- package/dist/types/modeler/solvers/z3/loader.d.ts +2 -3
- package/dist/types/modeler/solvers/z3/loader.d.ts.map +1 -1
- package/dist/types/modeler/solvers/z3/solver.d.ts +15 -5
- package/dist/types/modeler/solvers/z3/solver.d.ts.map +1 -1
- package/dist/types/modeler/types.d.ts +86 -1
- package/dist/types/modeler/types.d.ts.map +1 -1
- package/dist/types/modeler/validation.d.ts +56 -0
- package/dist/types/modeler/validation.d.ts.map +1 -0
- package/dist/types/modeler/variable.d.ts +48 -14
- package/dist/types/modeler/variable.d.ts.map +1 -1
- package/docs/examples/diet-sensitivity.md +90 -0
- package/docs/examples/ecommerce-coupons.md +106 -0
- package/docs/examples/index.md +57 -0
- package/docs/examples/knapsack.md +60 -0
- package/docs/examples/portfolio-qp.md +83 -0
- package/docs/examples/production.md +51 -0
- package/docs/examples/shift-scheduling.md +175 -0
- package/docs/examples/smt-security.md +74 -0
- package/docs/examples/transportation.md +90 -0
- package/docs/examples/traveling-salesperson.md +173 -0
- package/docs/examples/unsat-core.md +64 -0
- package/docs/examples/vehicle-routing.md +206 -0
- package/docs/getting-started/ai-agents.md +271 -0
- package/docs/getting-started/cross-origin.md +87 -0
- package/docs/getting-started/index.md +116 -0
- package/docs/getting-started/runtimes.md +227 -0
- package/docs/guide/constraints.md +177 -0
- package/docs/guide/decomposition.md +399 -0
- package/docs/guide/expressions.md +204 -0
- package/docs/guide/objectives.md +170 -0
- package/docs/guide/unsat-core.md +154 -0
- package/docs/guide/variables.md +188 -0
- package/docs/ja/getting-started/ai-agents.md +270 -0
- package/docs/solvers/custom-solver.md +525 -0
- package/docs/solvers/glpk.md +66 -0
- package/docs/solvers/highs.md +115 -0
- package/docs/solvers/index.md +42 -0
- package/docs/solvers/z3.md +78 -0
- package/docs/zh/getting-started/ai-agents.md +270 -0
- package/llms-full.txt +4065 -0
- package/llms.txt +201 -0
- package/package.json +32 -16
- package/skills/washi/SKILL.md +197 -0
- package/dist/browser/browser-runtime-D13gHOT5.js +0 -4189
- package/dist/browser/loader-CVt4CloI.js +0 -58
- package/dist/lib/async-mutex-Duo4jwzn.js +0 -195
- package/dist/lib/constraint-BRuB3ooC.js +0 -90
- package/dist/lib/loader-Dti0v9yC.js +0 -50
- package/dist/lib/registry-DksqCSjI.js +0 -32
package/dist/browser/washi.js
CHANGED
|
@@ -1,97 +1,182 @@
|
|
|
1
|
-
import { a as e,
|
|
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
|
|
4
|
-
|
|
3
|
+
function s(e) {
|
|
4
|
+
if (e === void 0) return "Minimize";
|
|
5
|
+
if (typeof e == "string") {
|
|
6
|
+
let t = e.toLowerCase();
|
|
7
|
+
if (t === "maximize") return "Maximize";
|
|
8
|
+
if (t === "minimize") return "Minimize";
|
|
9
|
+
}
|
|
10
|
+
throw Error(`Invalid optimization sense "${String(e)}": expected "Maximize", "Minimize", "maximize", or "minimize".`);
|
|
5
11
|
}
|
|
6
12
|
//#endregion
|
|
7
13
|
//#region src/modeler/boolean-expr.ts
|
|
8
|
-
var
|
|
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
|
+
}
|
|
19
|
+
var u = class {
|
|
9
20
|
and(e) {
|
|
10
|
-
return new
|
|
21
|
+
return new f("and", [this, l(e, "and")]);
|
|
11
22
|
}
|
|
12
23
|
or(e) {
|
|
13
|
-
return new
|
|
24
|
+
return new f("or", [this, l(e, "or")]);
|
|
14
25
|
}
|
|
15
26
|
implies(e) {
|
|
16
|
-
return new
|
|
27
|
+
return new f("implies", [this, l(e, "implies")]);
|
|
17
28
|
}
|
|
18
29
|
xor(e) {
|
|
19
|
-
return new
|
|
30
|
+
return new f("xor", [this, l(e, "xor")]);
|
|
20
31
|
}
|
|
21
32
|
not() {
|
|
22
|
-
return new
|
|
33
|
+
return new f("not", [this]);
|
|
23
34
|
}
|
|
24
|
-
},
|
|
35
|
+
}, d = class extends u {
|
|
25
36
|
id;
|
|
26
37
|
name;
|
|
27
38
|
value = null;
|
|
28
39
|
constructor(e) {
|
|
29
|
-
super(), this.id = ++
|
|
40
|
+
super(), this.id = ++c, this.name = e || `p_${this.id}`;
|
|
30
41
|
}
|
|
31
42
|
toString() {
|
|
32
43
|
return this.name;
|
|
33
44
|
}
|
|
34
|
-
},
|
|
45
|
+
}, f = class extends u {
|
|
35
46
|
op;
|
|
36
47
|
children;
|
|
37
48
|
constructor(e, t) {
|
|
38
|
-
super(), this.op = e, this.children = t;
|
|
49
|
+
super(), this.op = e, this.children = t.map((t) => l(t, e));
|
|
39
50
|
}
|
|
40
51
|
toString() {
|
|
41
52
|
return this.op === "not" ? `not(${this.children[0].toString()})` : `(${this.children.map((e) => e.toString()).join(` ${this.op} `)})`;
|
|
42
53
|
}
|
|
43
54
|
};
|
|
44
|
-
function
|
|
55
|
+
function p(...e) {
|
|
45
56
|
if (e.length === 0) throw Error("and() requires at least one expression");
|
|
46
|
-
return new
|
|
57
|
+
return new f("and", e);
|
|
47
58
|
}
|
|
48
|
-
function
|
|
59
|
+
function m(...e) {
|
|
49
60
|
if (e.length === 0) throw Error("or() requires at least one expression");
|
|
50
|
-
return new
|
|
61
|
+
return new f("or", e);
|
|
51
62
|
}
|
|
52
|
-
function
|
|
53
|
-
return new
|
|
63
|
+
function h(e) {
|
|
64
|
+
return new f("not", [e]);
|
|
54
65
|
}
|
|
55
|
-
function
|
|
56
|
-
return new
|
|
66
|
+
function g(e, t) {
|
|
67
|
+
return new f("implies", [e, t]);
|
|
57
68
|
}
|
|
58
|
-
function
|
|
69
|
+
function _(...e) {
|
|
59
70
|
if (e.length === 0) throw Error("xor() requires at least one expression");
|
|
60
|
-
return new
|
|
71
|
+
return new f("xor", e);
|
|
61
72
|
}
|
|
62
73
|
//#endregion
|
|
63
74
|
//#region src/modeler/constraint.ts
|
|
64
|
-
var
|
|
75
|
+
var v = 0, y = class e {
|
|
76
|
+
kind = "constraint";
|
|
65
77
|
id;
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
78
|
+
_lhs;
|
|
79
|
+
_sense;
|
|
80
|
+
_rhs;
|
|
81
|
+
_name;
|
|
82
|
+
hasExplicitName;
|
|
83
|
+
ownerModel = null;
|
|
70
84
|
slack = null;
|
|
71
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
|
+
}
|
|
72
92
|
constructor(e, t, n, r) {
|
|
73
|
-
this.id = ++
|
|
93
|
+
this.id = ++v, this._lhs = e, this._sense = t, this._rhs = n;
|
|
94
|
+
let i = typeof r == "string" ? r.trim() : void 0;
|
|
95
|
+
i && i.length > 0 ? (this._name = i, this.hasExplicitName = !0) : (this._name = `c_${this.id}`, this.hasExplicitName = !1);
|
|
96
|
+
}
|
|
97
|
+
get lhs() {
|
|
98
|
+
return this._lhs;
|
|
99
|
+
}
|
|
100
|
+
set lhs(e) {
|
|
101
|
+
this._lhs !== e && (this._lhs = e, this.ownerModel?.notifyMutation?.());
|
|
102
|
+
}
|
|
103
|
+
get sense() {
|
|
104
|
+
return this._sense;
|
|
105
|
+
}
|
|
106
|
+
set sense(e) {
|
|
107
|
+
this._sense !== e && (this._sense = e, this.ownerModel?.notifyMutation?.());
|
|
108
|
+
}
|
|
109
|
+
get rhs() {
|
|
110
|
+
return this._rhs;
|
|
111
|
+
}
|
|
112
|
+
set rhs(e) {
|
|
113
|
+
Object.is(this._rhs, e) || (this._rhs = e, this.ownerModel?.notifyMutation?.());
|
|
114
|
+
}
|
|
115
|
+
get name() {
|
|
116
|
+
return this._name;
|
|
117
|
+
}
|
|
118
|
+
set name(e) {
|
|
119
|
+
this._name !== e && (this._name = e, this.ownerModel?.notifyMutation?.()), this.hasExplicitName = !0;
|
|
120
|
+
}
|
|
121
|
+
_assignModelName(e, t) {
|
|
122
|
+
this._name = e, this.hasExplicitName = t;
|
|
74
123
|
}
|
|
75
124
|
and(e) {
|
|
76
|
-
return new
|
|
125
|
+
return new f("and", [this, e]);
|
|
77
126
|
}
|
|
78
127
|
or(e) {
|
|
79
|
-
return new
|
|
128
|
+
return new f("or", [this, e]);
|
|
80
129
|
}
|
|
81
130
|
implies(e) {
|
|
82
|
-
return new
|
|
131
|
+
return new f("implies", [this, e]);
|
|
83
132
|
}
|
|
84
133
|
xor(e) {
|
|
85
|
-
return new
|
|
134
|
+
return new f("xor", [this, e]);
|
|
86
135
|
}
|
|
87
136
|
not() {
|
|
88
|
-
return new
|
|
137
|
+
return new f("not", [this]);
|
|
138
|
+
}
|
|
139
|
+
add(e) {
|
|
140
|
+
throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
141
|
+
}
|
|
142
|
+
sub(e) {
|
|
143
|
+
throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
144
|
+
}
|
|
145
|
+
mul(e) {
|
|
146
|
+
throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
147
|
+
}
|
|
148
|
+
div(e) {
|
|
149
|
+
throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
150
|
+
}
|
|
151
|
+
neg() {
|
|
152
|
+
throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
153
|
+
}
|
|
154
|
+
le(e, t) {
|
|
155
|
+
throw Error("Cannot compare a Constraint in (<=): expected a number, Var, or LinExpr.");
|
|
156
|
+
}
|
|
157
|
+
ge(e, t) {
|
|
158
|
+
throw Error("Cannot compare a Constraint in (>=): expected a number, Var, or LinExpr.");
|
|
159
|
+
}
|
|
160
|
+
eq(e, t) {
|
|
161
|
+
throw Error("Cannot compare a Constraint in (==): expected a number, Var, or LinExpr.");
|
|
162
|
+
}
|
|
163
|
+
get value() {
|
|
164
|
+
throw Error("Cannot read numeric value of a Constraint: expected a Var, LinExpr, or QuadExpr.");
|
|
165
|
+
}
|
|
166
|
+
get constant() {
|
|
167
|
+
throw Error("Cannot read numeric constant of a Constraint: expected a LinExpr or QuadExpr.");
|
|
168
|
+
}
|
|
169
|
+
clone() {
|
|
170
|
+
return new e(this._lhs.clone(), this._sense, this._rhs, this.hasExplicitName ? this._name : void 0);
|
|
89
171
|
}
|
|
90
172
|
toString() {
|
|
91
173
|
let e = this.sense === "==" ? "=" : this.sense;
|
|
92
174
|
return `${this.name}: ${this.lhs.toString()} ${e} ${this.rhs}`;
|
|
93
175
|
}
|
|
94
176
|
};
|
|
177
|
+
function b(e) {
|
|
178
|
+
return e instanceof y || typeof e == "object" && !!e && "sense" in e && "lhs" in e && "rhs" in e;
|
|
179
|
+
}
|
|
95
180
|
//#endregion
|
|
96
181
|
//#region src/modeler/quad-expr.ts
|
|
97
182
|
function x(e, t) {
|
|
@@ -99,6 +184,7 @@ function x(e, t) {
|
|
|
99
184
|
return n <= r ? `${n}:${r}` : `${r}:${n}`;
|
|
100
185
|
}
|
|
101
186
|
var S = class e {
|
|
187
|
+
kind = "quadratic";
|
|
102
188
|
linearTerms;
|
|
103
189
|
quadTerms;
|
|
104
190
|
constant;
|
|
@@ -115,80 +201,72 @@ var S = class e {
|
|
|
115
201
|
return r ? r.coeff : 0;
|
|
116
202
|
}
|
|
117
203
|
add(t) {
|
|
204
|
+
if (b(t)) throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
118
205
|
let n = this.clone();
|
|
119
206
|
if (typeof t == "number") return n.constant += t, n;
|
|
120
207
|
if (t instanceof e) {
|
|
121
208
|
for (let [e, r] of t.quadTerms) {
|
|
122
209
|
let t = n.quadTerms.get(e), i = (t ? t.coeff : 0) + r.coeff;
|
|
123
|
-
|
|
210
|
+
i === 0 ? n.quadTerms.delete(e) : n.quadTerms.set(e, {
|
|
124
211
|
var1: r.var1,
|
|
125
212
|
var2: r.var2,
|
|
126
213
|
coeff: i
|
|
127
214
|
});
|
|
128
215
|
}
|
|
129
216
|
for (let [e, r] of t.linearTerms) {
|
|
130
|
-
let t = (n.linearTerms.get(e)
|
|
131
|
-
|
|
217
|
+
let t = (n.linearTerms.get(e) ?? 0) + r;
|
|
218
|
+
t === 0 ? n.linearTerms.delete(e) : n.linearTerms.set(e, t);
|
|
132
219
|
}
|
|
133
220
|
return n.constant += t.constant, n;
|
|
134
221
|
}
|
|
135
222
|
if ("terms" in t && t.terms instanceof Map) {
|
|
136
223
|
for (let [e, r] of t.terms) {
|
|
137
|
-
let t = (n.linearTerms.get(e)
|
|
138
|
-
|
|
224
|
+
let t = (n.linearTerms.get(e) ?? 0) + r;
|
|
225
|
+
t === 0 ? n.linearTerms.delete(e) : n.linearTerms.set(e, t);
|
|
139
226
|
}
|
|
140
227
|
return n.constant += t.constant, n;
|
|
141
228
|
}
|
|
142
|
-
let r = t, i = (n.linearTerms.get(r)
|
|
143
|
-
return
|
|
229
|
+
let r = t, i = (n.linearTerms.get(r) ?? 0) + 1;
|
|
230
|
+
return i === 0 ? n.linearTerms.delete(r) : n.linearTerms.set(r, i), n;
|
|
144
231
|
}
|
|
145
|
-
sub(
|
|
146
|
-
|
|
232
|
+
sub(e) {
|
|
233
|
+
if (b(e)) throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
234
|
+
return typeof e == "number" ? this.add(-e) : this.add(e.mul(-1));
|
|
147
235
|
}
|
|
148
236
|
mul(t) {
|
|
237
|
+
if (b(t)) throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
149
238
|
if (typeof t == "number") {
|
|
150
|
-
let n =
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
239
|
+
let n = this.linearTerms.size > 0 || this.quadTerms.size > 0, r = this.constant === 0 && n ? 0 : this.constant * t;
|
|
240
|
+
if (this.constant !== 0 && t !== 0 && r === 0) throw Error("Constant multiplication underflows to zero.");
|
|
241
|
+
let i = new e(/* @__PURE__ */ new Map(), /* @__PURE__ */ new Map(), r);
|
|
242
|
+
for (let [e, n] of this.linearTerms) {
|
|
243
|
+
let r = n * t;
|
|
244
|
+
if (n !== 0 && t !== 0 && r === 0) throw Error("Coefficient multiplication underflows to zero.");
|
|
245
|
+
r !== 0 && i.linearTerms.set(e, r);
|
|
154
246
|
}
|
|
155
|
-
for (let [e,
|
|
156
|
-
let
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
247
|
+
for (let [e, n] of this.quadTerms) {
|
|
248
|
+
let r = n.coeff * t;
|
|
249
|
+
if (n.coeff !== 0 && t !== 0 && r === 0) throw Error("Coefficient multiplication underflows to zero.");
|
|
250
|
+
r !== 0 && i.quadTerms.set(e, {
|
|
251
|
+
var1: n.var1,
|
|
252
|
+
var2: n.var2,
|
|
253
|
+
coeff: r
|
|
161
254
|
});
|
|
162
255
|
}
|
|
163
|
-
return
|
|
164
|
-
}
|
|
165
|
-
if ("id" in t && "name" in t && !("terms" in t) && !("quadTerms" in t)) {
|
|
166
|
-
if (this.quadTerms.size > 0) throw Error("Multiplication creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)");
|
|
167
|
-
let n = new e();
|
|
168
|
-
Math.abs(this.constant) >= 1e-12 && n.linearTerms.set(t, this.constant);
|
|
169
|
-
for (let [r, i] of this.linearTerms) n = n.add(e.fromProduct(r, t, i));
|
|
170
|
-
return n;
|
|
256
|
+
return i;
|
|
171
257
|
}
|
|
172
|
-
let n = t, r = "quadTerms" in
|
|
258
|
+
let n = "id" in t && "name" in t && !("terms" in t) && !("quadTerms" in t), r = "quadTerms" in t ? t.quadTerms.size : 0, i = n ? /* @__PURE__ */ new Map([[t, 1]]) : "quadTerms" in t ? t.linearTerms : t.terms, a = n ? 0 : t.constant;
|
|
173
259
|
if (this.quadTerms.size > 0 && (r > 0 || i.size > 0) || r > 0 && this.linearTerms.size > 0) throw Error("Multiplication creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)");
|
|
174
|
-
if (r === 0 && i.size === 0) return this.mul(
|
|
175
|
-
if (this.quadTerms.size === 0 && this.linearTerms.size === 0) {
|
|
176
|
-
let
|
|
177
|
-
|
|
178
|
-
let r = new e();
|
|
179
|
-
r.constant = t.constant;
|
|
180
|
-
for (let [e, n] of t.terms) r.linearTerms.set(e, n);
|
|
181
|
-
return r;
|
|
260
|
+
if (r === 0 && i.size === 0) return this.mul(a);
|
|
261
|
+
if (this.quadTerms.size === 0 && this.linearTerms.size === 0 && !n) {
|
|
262
|
+
let n = t.mul(this.constant);
|
|
263
|
+
return "quadTerms" in n ? n : new e(n.terms, /* @__PURE__ */ new Map(), n.constant);
|
|
182
264
|
}
|
|
183
|
-
|
|
184
|
-
if (a.constant = this.constant * n.constant, Math.abs(n.constant) >= 1e-12) for (let [e, t] of this.linearTerms) a.linearTerms.set(e, (a.linearTerms.get(e) || 0) + t * n.constant);
|
|
185
|
-
if (Math.abs(this.constant) >= 1e-12) for (let [e, t] of i) a.linearTerms.set(e, (a.linearTerms.get(e) || 0) + t * this.constant);
|
|
186
|
-
for (let [t, n] of this.linearTerms) for (let [r, o] of i) a = a.add(e.fromProduct(t, r, n * o));
|
|
187
|
-
return a;
|
|
265
|
+
return e.multiplyLinearTerms(this.constant, this.linearTerms, a, i);
|
|
188
266
|
}
|
|
189
|
-
div(
|
|
190
|
-
|
|
191
|
-
return this.mul(1 /
|
|
267
|
+
div(t) {
|
|
268
|
+
let n = e.extractScalarDivisor(t, "QuadExpr.div()");
|
|
269
|
+
return this.mul(1 / n);
|
|
192
270
|
}
|
|
193
271
|
neg() {
|
|
194
272
|
return this.mul(-1);
|
|
@@ -205,8 +283,34 @@ var S = class e {
|
|
|
205
283
|
}
|
|
206
284
|
return e;
|
|
207
285
|
}
|
|
208
|
-
|
|
209
|
-
return this.
|
|
286
|
+
le(e, t) {
|
|
287
|
+
return this.toConstraint("<=", e, t);
|
|
288
|
+
}
|
|
289
|
+
ge(e, t) {
|
|
290
|
+
return this.toConstraint(">=", e, t);
|
|
291
|
+
}
|
|
292
|
+
eq(e, t) {
|
|
293
|
+
return this.toConstraint("==", e, t);
|
|
294
|
+
}
|
|
295
|
+
toConstraint(e, t, n) {
|
|
296
|
+
if (this.quadTerms.size > 0) throw Error(`Quadratic expressions are not supported in linear constraints (${e}): quadratic terms are only allowed in objectives.`);
|
|
297
|
+
let r = new C(this.linearTerms, this.constant);
|
|
298
|
+
return e === "<=" ? r.le(t, n) : e === ">=" ? r.ge(t, n) : r.eq(t, n);
|
|
299
|
+
}
|
|
300
|
+
and(e) {
|
|
301
|
+
throw Error("Cannot use an arithmetic expression without a comparison operator (<=, >=, ==) in logical 'and': expected a BoolVar, Constraint, or BoolOp.");
|
|
302
|
+
}
|
|
303
|
+
or(e) {
|
|
304
|
+
throw Error("Cannot use an arithmetic expression without a comparison operator (<=, >=, ==) in logical 'or': expected a BoolVar, Constraint, or BoolOp.");
|
|
305
|
+
}
|
|
306
|
+
implies(e) {
|
|
307
|
+
throw Error("Cannot use an arithmetic expression without a comparison operator (<=, >=, ==) in logical 'implies': expected a BoolVar, Constraint, or BoolOp.");
|
|
308
|
+
}
|
|
309
|
+
xor(e) {
|
|
310
|
+
throw Error("Cannot use an arithmetic expression without a comparison operator (<=, >=, ==) in logical 'xor': expected a BoolVar, Constraint, or BoolOp.");
|
|
311
|
+
}
|
|
312
|
+
not() {
|
|
313
|
+
throw Error("Cannot use an arithmetic expression without a comparison operator (<=, >=, ==) in logical 'not': expected a BoolVar, Constraint, or BoolOp.");
|
|
210
314
|
}
|
|
211
315
|
toString() {
|
|
212
316
|
let e = [], t = !0;
|
|
@@ -225,76 +329,104 @@ var S = class e {
|
|
|
225
329
|
return e.join(" ") || "0";
|
|
226
330
|
}
|
|
227
331
|
static fromProduct(t, n, r = 1) {
|
|
228
|
-
let i = new e()
|
|
332
|
+
let i = new e();
|
|
333
|
+
if (r === 0) return i;
|
|
334
|
+
let a = x(t, n);
|
|
229
335
|
return i.quadTerms.set(a, {
|
|
230
336
|
var1: t.id <= n.id ? t : n,
|
|
231
337
|
var2: t.id <= n.id ? n : t,
|
|
232
338
|
coeff: r
|
|
233
339
|
}), i;
|
|
234
340
|
}
|
|
341
|
+
static multiplyLinearTerms(t, n, r, i) {
|
|
342
|
+
let a = n.size > 0 || i.size > 0, o = (t === 0 || r === 0) && a ? 0 : t * r;
|
|
343
|
+
if (t !== 0 && r !== 0 && o === 0) throw Error("Constant multiplication underflows to zero.");
|
|
344
|
+
let s = new e(/* @__PURE__ */ new Map(), /* @__PURE__ */ new Map(), o === 0 ? 0 : o);
|
|
345
|
+
if (r !== 0) for (let [e, t] of n) {
|
|
346
|
+
let n = t * r;
|
|
347
|
+
if (t !== 0 && n === 0) throw Error("Coefficient multiplication underflows to zero.");
|
|
348
|
+
n !== 0 && s.linearTerms.set(e, n);
|
|
349
|
+
}
|
|
350
|
+
if (t !== 0) for (let [e, n] of i) {
|
|
351
|
+
let r = s.linearTerms.get(e) ?? 0, i = n * t;
|
|
352
|
+
if (n !== 0 && i === 0) throw Error("Coefficient multiplication underflows to zero.");
|
|
353
|
+
let a = r + i;
|
|
354
|
+
a === 0 ? s.linearTerms.delete(e) : s.linearTerms.set(e, a);
|
|
355
|
+
}
|
|
356
|
+
for (let [t, r] of n) for (let [n, a] of i) {
|
|
357
|
+
let i = r * a;
|
|
358
|
+
if (r !== 0 && a !== 0 && i === 0) throw Error("Coefficient multiplication underflows to zero.");
|
|
359
|
+
s = s.add(e.fromProduct(t, n, i));
|
|
360
|
+
}
|
|
361
|
+
return s;
|
|
362
|
+
}
|
|
363
|
+
static extractScalarDivisor(e, t) {
|
|
364
|
+
if (b(e)) throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
365
|
+
if (typeof e == "number") {
|
|
366
|
+
if (e === 0) throw Error(`Division by zero in ${t}`);
|
|
367
|
+
return e;
|
|
368
|
+
}
|
|
369
|
+
let n = "quadTerms" in e ? e.linearTerms.size : e.terms.size, r = "quadTerms" in e ? e.quadTerms.size : 0;
|
|
370
|
+
if (n > 0 || r > 0) throw Error("Cannot divide by variable in expression");
|
|
371
|
+
if (e.constant === 0) throw Error(`Division by zero in ${t}`);
|
|
372
|
+
return e.constant;
|
|
373
|
+
}
|
|
235
374
|
}, C = class e {
|
|
375
|
+
kind = "linear";
|
|
236
376
|
terms;
|
|
237
377
|
constant;
|
|
238
378
|
constructor(e = /* @__PURE__ */ new Map(), t = 0) {
|
|
239
379
|
this.terms = new Map(e), this.constant = t;
|
|
240
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
|
+
}
|
|
241
388
|
clone() {
|
|
242
389
|
return new e(this.terms, this.constant);
|
|
243
390
|
}
|
|
244
391
|
add(e) {
|
|
392
|
+
if (b(e)) throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
245
393
|
if (e instanceof S) return e.add(this);
|
|
246
394
|
let t = this.clone();
|
|
247
395
|
if (typeof e == "number") t.constant += e;
|
|
248
396
|
else if ("terms" in e) {
|
|
249
397
|
for (let [n, r] of e.terms) {
|
|
250
|
-
let e = (t.terms.get(n)
|
|
251
|
-
|
|
398
|
+
let e = (t.terms.get(n) ?? 0) + r;
|
|
399
|
+
e === 0 ? t.terms.delete(n) : t.terms.set(n, e);
|
|
252
400
|
}
|
|
253
401
|
t.constant += e.constant;
|
|
254
402
|
} else {
|
|
255
|
-
let n = (t.terms.get(e)
|
|
256
|
-
|
|
403
|
+
let n = (t.terms.get(e) ?? 0) + 1;
|
|
404
|
+
n === 0 ? t.terms.delete(e) : t.terms.set(e, n);
|
|
257
405
|
}
|
|
258
406
|
return t;
|
|
259
407
|
}
|
|
260
408
|
sub(e) {
|
|
261
|
-
|
|
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));
|
|
262
411
|
}
|
|
263
412
|
mul(t) {
|
|
413
|
+
if (b(t)) throw Error("Cannot perform arithmetic on a Constraint: expected a number, Var, LinExpr, or QuadExpr.");
|
|
264
414
|
if (typeof t == "number") {
|
|
265
|
-
let n =
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
415
|
+
let n = this.constant === 0 && this.terms.size > 0 ? 0 : this.constant * t;
|
|
416
|
+
if (this.constant !== 0 && t !== 0 && n === 0) throw Error("Constant multiplication underflows to zero.");
|
|
417
|
+
let r = new e(/* @__PURE__ */ new Map(), n);
|
|
418
|
+
for (let [e, n] of this.terms) {
|
|
419
|
+
let i = n * t;
|
|
420
|
+
if (n !== 0 && t !== 0 && i === 0) throw Error("Coefficient multiplication underflows to zero.");
|
|
421
|
+
i !== 0 && r.terms.set(e, i);
|
|
269
422
|
}
|
|
270
|
-
return
|
|
271
|
-
}
|
|
272
|
-
if (t instanceof D || typeof t == "object" && t && "id" in t && !("terms" in t) && !("quadTerms" in t)) {
|
|
273
|
-
let e = t, n = new S();
|
|
274
|
-
Math.abs(this.constant) >= 1e-12 && n.linearTerms.set(e, this.constant);
|
|
275
|
-
for (let [t, r] of this.terms) n = n.add(S.fromProduct(t, e, r));
|
|
276
|
-
return n;
|
|
277
|
-
}
|
|
278
|
-
if (t instanceof S) {
|
|
279
|
-
if (t.quadTerms.size > 0 && this.terms.size > 0) throw Error("Multiplication creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)");
|
|
280
|
-
if (this.terms.size === 0) return t.mul(this.constant);
|
|
281
|
-
let e = new S();
|
|
282
|
-
if (e.constant = this.constant * t.constant, Math.abs(t.constant) >= 1e-12) for (let [n, r] of this.terms) e.linearTerms.set(n, (e.linearTerms.get(n) || 0) + r * t.constant);
|
|
283
|
-
if (Math.abs(this.constant) >= 1e-12) for (let [n, r] of t.linearTerms) e.linearTerms.set(n, (e.linearTerms.get(n) || 0) + r * this.constant);
|
|
284
|
-
for (let [n, r] of this.terms) for (let [i, a] of t.linearTerms) e = e.add(S.fromProduct(n, i, r * a));
|
|
285
|
-
return e;
|
|
423
|
+
return r;
|
|
286
424
|
}
|
|
287
|
-
|
|
288
|
-
if (t.terms.size === 0) return this.mul(t.constant);
|
|
289
|
-
let n = new S();
|
|
290
|
-
if (n.constant = this.constant * t.constant, Math.abs(t.constant) >= 1e-12) for (let [e, r] of this.terms) n.linearTerms.set(e, (n.linearTerms.get(e) || 0) + r * t.constant);
|
|
291
|
-
if (Math.abs(this.constant) >= 1e-12) for (let [e, r] of t.terms) n.linearTerms.set(e, (n.linearTerms.get(e) || 0) + r * this.constant);
|
|
292
|
-
for (let [e, r] of this.terms) for (let [i, a] of t.terms) n = n.add(S.fromProduct(e, i, r * a));
|
|
293
|
-
return n;
|
|
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);
|
|
294
426
|
}
|
|
295
427
|
div(e) {
|
|
296
|
-
|
|
297
|
-
return this.mul(1 /
|
|
428
|
+
let t = S.extractScalarDivisor(e, "LinExpr.div()");
|
|
429
|
+
return this.mul(1 / t);
|
|
298
430
|
}
|
|
299
431
|
neg() {
|
|
300
432
|
return this.mul(-1);
|
|
@@ -307,32 +439,41 @@ var S = class e {
|
|
|
307
439
|
}
|
|
308
440
|
return e;
|
|
309
441
|
}
|
|
310
|
-
getValue() {
|
|
311
|
-
return this.value;
|
|
312
|
-
}
|
|
313
442
|
le(e, t) {
|
|
314
443
|
return this.toConstraint("<=", e, t);
|
|
315
444
|
}
|
|
316
|
-
lessThanOrEqual(e, t) {
|
|
317
|
-
return this.le(e, t);
|
|
318
|
-
}
|
|
319
445
|
ge(e, t) {
|
|
320
446
|
return this.toConstraint(">=", e, t);
|
|
321
447
|
}
|
|
322
|
-
greaterThanOrEqual(e, t) {
|
|
323
|
-
return this.ge(e, t);
|
|
324
|
-
}
|
|
325
448
|
eq(e, t) {
|
|
326
449
|
return this.toConstraint("==", e, t);
|
|
327
450
|
}
|
|
328
|
-
equalTo(e, t) {
|
|
329
|
-
return this.eq(e, t);
|
|
330
|
-
}
|
|
331
451
|
toConstraint(t, n, r) {
|
|
332
452
|
let i = this.clone(), a = 0;
|
|
333
|
-
typeof n == "number"
|
|
453
|
+
if (typeof n == "number") a = n;
|
|
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) {
|
|
456
|
+
let r = n;
|
|
457
|
+
if (r.quadTerms.size > 0) throw Error(`Quadratic expressions are not supported in linear constraints (${t}): quadratic terms are only allowed in objectives.`);
|
|
458
|
+
i = i.sub(new e(r.linearTerms, 0)), a = r.constant;
|
|
459
|
+
} else "terms" in n ? (i = i.sub(new e(n.terms, 0)), a = n.constant) : i = i.sub(n);
|
|
334
460
|
let o = a - i.constant;
|
|
335
|
-
return i.constant = 0, new
|
|
461
|
+
return i.constant = 0, new y(i, t, o, r);
|
|
462
|
+
}
|
|
463
|
+
and(e) {
|
|
464
|
+
throw Error("Cannot use an arithmetic expression without a comparison operator (<=, >=, ==) in logical 'and': expected a BoolVar, Constraint, or BoolOp.");
|
|
465
|
+
}
|
|
466
|
+
or(e) {
|
|
467
|
+
throw Error("Cannot use an arithmetic expression without a comparison operator (<=, >=, ==) in logical 'or': expected a BoolVar, Constraint, or BoolOp.");
|
|
468
|
+
}
|
|
469
|
+
implies(e) {
|
|
470
|
+
throw Error("Cannot use an arithmetic expression without a comparison operator (<=, >=, ==) in logical 'implies': expected a BoolVar, Constraint, or BoolOp.");
|
|
471
|
+
}
|
|
472
|
+
xor(e) {
|
|
473
|
+
throw Error("Cannot use an arithmetic expression without a comparison operator (<=, >=, ==) in logical 'xor': expected a BoolVar, Constraint, or BoolOp.");
|
|
474
|
+
}
|
|
475
|
+
not() {
|
|
476
|
+
throw Error("Cannot use an arithmetic expression without a comparison operator (<=, >=, ==) in logical 'not': expected a BoolVar, Constraint, or BoolOp.");
|
|
336
477
|
}
|
|
337
478
|
toString() {
|
|
338
479
|
let e = [], t = !0;
|
|
@@ -352,17 +493,26 @@ function w(e, t) {
|
|
|
352
493
|
function i(e) {
|
|
353
494
|
if (e != null) {
|
|
354
495
|
if (typeof e == "number") r += e;
|
|
355
|
-
else if (typeof e == "object" && "
|
|
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) {
|
|
498
|
+
let t = e;
|
|
499
|
+
if (t.quadTerms.size > 0) throw Error("Quadratic expressions are not supported in sum(): sum() produces a linear expression (LinExpr).");
|
|
500
|
+
for (let [e, r] of t.linearTerms) {
|
|
501
|
+
let t = n.get(e) ?? 0;
|
|
502
|
+
n.set(e, t + r);
|
|
503
|
+
}
|
|
504
|
+
r += t.constant;
|
|
505
|
+
} else if (typeof e == "object" && "terms" in e) {
|
|
356
506
|
let t = e;
|
|
357
507
|
for (let [e, r] of t.terms) {
|
|
358
|
-
let t = n.get(e)
|
|
508
|
+
let t = n.get(e) ?? 0;
|
|
359
509
|
n.set(e, t + r);
|
|
360
510
|
}
|
|
361
511
|
r += t.constant;
|
|
362
|
-
} else {
|
|
363
|
-
let t = e, r = n.get(t)
|
|
512
|
+
} else if (typeof e == "object" && "id" in e && "name" in e && "lb" in e && "ub" in e) {
|
|
513
|
+
let t = e, r = n.get(t) ?? 0;
|
|
364
514
|
n.set(t, r + 1);
|
|
365
|
-
}
|
|
515
|
+
} else throw Error("Unsupported item in sum(): expected a number, Var, or LinExpr.");
|
|
366
516
|
}
|
|
367
517
|
}
|
|
368
518
|
if (typeof e == "number") {
|
|
@@ -372,41 +522,55 @@ function w(e, t) {
|
|
|
372
522
|
let n = 0;
|
|
373
523
|
for (let r of e) i(t ? t(r, n++) : r);
|
|
374
524
|
}
|
|
375
|
-
for (let [e, t] of n)
|
|
525
|
+
for (let [e, t] of n) t === 0 && n.delete(e);
|
|
376
526
|
return new C(n, r);
|
|
377
527
|
}
|
|
378
|
-
function
|
|
528
|
+
function T(e, t) {
|
|
379
529
|
let n = /* @__PURE__ */ new Map(), r = 0;
|
|
380
530
|
function i(e) {
|
|
381
|
-
return typeof e == "object" && !!e && typeof e.id == "number" && typeof e.name == "string" && typeof e.mul == "function" && typeof e.le == "function";
|
|
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";
|
|
382
532
|
}
|
|
383
533
|
function a(e) {
|
|
384
534
|
return i(e) || e instanceof C || e instanceof S;
|
|
385
535
|
}
|
|
386
|
-
function o(e, t) {
|
|
387
|
-
if (
|
|
388
|
-
|
|
536
|
+
function o(e, t, a) {
|
|
537
|
+
if (!Number.isFinite(e)) throw Error(`Invalid non-finite coefficient "${e}" in dot() at '${a || "root"}'.`);
|
|
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) {
|
|
540
|
+
if (!Number.isFinite(t.constant)) throw Error(`Invalid non-finite constant "${t.constant}" in dot() at '${a || "root"}'.`);
|
|
541
|
+
let i = e === 0 || t.constant === 0 ? 0 : e * t.constant;
|
|
542
|
+
if (e !== 0 && t.constant !== 0 && i === 0) throw Error("Constant multiplication underflows to zero.");
|
|
543
|
+
if (!Number.isFinite(i)) throw Error(`Coefficient multiplication overflows finite floating-point range in dot() at '${a || "root"}'.`);
|
|
544
|
+
let o = r + i;
|
|
545
|
+
if (!Number.isFinite(o)) throw Error(`Constant accumulation overflows finite floating-point range in dot() at '${a || "root"}'.`);
|
|
546
|
+
r = o;
|
|
389
547
|
for (let [r, i] of t.terms) {
|
|
390
|
-
|
|
391
|
-
|
|
548
|
+
if (!Number.isFinite(i)) throw Error(`Invalid non-finite coefficient "${i}" in dot() at '${a || "root"}'.`);
|
|
549
|
+
let t = e * i;
|
|
550
|
+
if (e !== 0 && i !== 0 && t === 0) throw Error("Coefficient multiplication underflows to zero.");
|
|
551
|
+
if (!Number.isFinite(t)) throw Error(`Coefficient multiplication overflows finite floating-point range in dot() at '${a || "root"}'.`);
|
|
552
|
+
let o = (n.get(r) ?? 0) + t;
|
|
553
|
+
if (!Number.isFinite(o)) throw Error(`Coefficient accumulation overflows finite floating-point range in dot() at '${a || "root"}'.`);
|
|
554
|
+
n.set(r, o);
|
|
392
555
|
}
|
|
393
|
-
r += e * t.constant;
|
|
394
556
|
} else if (i(t)) {
|
|
395
|
-
let r = t, i = n.get(r)
|
|
396
|
-
|
|
397
|
-
|
|
557
|
+
let r = t, i = (n.get(r) ?? 0) + e;
|
|
558
|
+
if (!Number.isFinite(i)) throw Error(`Coefficient accumulation overflows finite floating-point range in dot() at '${a || "root"}'.`);
|
|
559
|
+
n.set(r, i);
|
|
560
|
+
} else throw Error(`Cannot multiply number by non-variable/expression operand in dot() at '${a || "root"}'.`);
|
|
398
561
|
}
|
|
399
562
|
function s(e) {
|
|
400
|
-
return typeof e == "object" && !!e && !Array.isArray(e) && !a(e);
|
|
563
|
+
return typeof e == "object" && !!e && !Array.isArray(e) && !a(e) && !(e instanceof y) && e.kind !== "constraint";
|
|
401
564
|
}
|
|
402
565
|
function c(e, t, n = "") {
|
|
403
566
|
if (e === void 0 || t === void 0 || e === null || t === null) throw Error(`Nullish or undefined operand encountered in dot() at '${n || "root"}'.`);
|
|
567
|
+
if (typeof e == "number" && typeof t == "number") throw Error(`Cannot multiply two numbers in dot() at '${n || "root"}': expected one numeric coefficient and one Var or LinExpr.`);
|
|
404
568
|
if (typeof e == "number") {
|
|
405
|
-
o(e, t);
|
|
569
|
+
o(e, t, n);
|
|
406
570
|
return;
|
|
407
571
|
}
|
|
408
572
|
if (typeof t == "number") {
|
|
409
|
-
o(t, e);
|
|
573
|
+
o(t, e, n);
|
|
410
574
|
return;
|
|
411
575
|
}
|
|
412
576
|
if (Array.isArray(e) || Array.isArray(t)) {
|
|
@@ -417,21 +581,22 @@ function ee(e, t) {
|
|
|
417
581
|
}
|
|
418
582
|
let r = Array.isArray(e) ? e : t, i = Array.isArray(e) ? t : e;
|
|
419
583
|
if (s(i)) {
|
|
584
|
+
if (Object.getOwnPropertySymbols(i).length > 0) throw Error(`Symbol keys are not supported in dot() at '${n || "root"}'.`);
|
|
420
585
|
let a = Object.keys(i);
|
|
421
|
-
if (a.length
|
|
422
|
-
|
|
423
|
-
let
|
|
424
|
-
|
|
425
|
-
if (o.length > 0) throw Error(`Key mismatch in dot() at '${n || "root"}': missing indices [${o.join(", ")}] in numeric record.`);
|
|
586
|
+
if (a.length === r.length && a.every((e) => /^(?:0|[1-9]\d*)$/.test(e))) {
|
|
587
|
+
let a = [];
|
|
588
|
+
for (let e = 0; e < r.length; e++) Object.prototype.hasOwnProperty.call(i, e) || a.push(e);
|
|
589
|
+
if (a.length > 0) throw Error(`Key mismatch in dot() at '${n || "root"}': missing indices [${a.join(", ")}] in numeric record.`);
|
|
426
590
|
for (let i = 0; i < r.length; i++) c(e[i], t[i], n ? `${n}[${i}]` : `[${i}]`);
|
|
427
591
|
return;
|
|
428
592
|
}
|
|
429
|
-
throw Error(`Type mismatch in dot() at '${n || "root"}': one operand is an Array while the other is an Object with keys [${a.slice(0, 5).join(", ")}].`);
|
|
593
|
+
throw a.length > 0 && a.every((e) => /^(?:0|[1-9]\d*)$/.test(e)) ? Error(`Array length mismatch in dot() at '${n || "root"}': array has length ${r.length}, but object has ${a.length} indices.`) : Error(`Type mismatch in dot() at '${n || "root"}': one operand is an Array while the other is an Object with keys [${a.slice(0, 5).join(", ")}].`);
|
|
430
594
|
}
|
|
431
595
|
throw Error(`Type mismatch in dot() at '${n || "root"}': one operand is an Array while the other is not.`);
|
|
432
596
|
}
|
|
433
597
|
if (s(e) && s(t)) {
|
|
434
|
-
|
|
598
|
+
if (Object.getOwnPropertySymbols(e).length > 0 || Object.getOwnPropertySymbols(t).length > 0) throw Error(`Symbol keys are not supported in dot() at '${n || "root"}'.`);
|
|
599
|
+
let r = Object.keys(e), i = Object.keys(t), a = r.filter((e) => !Object.prototype.hasOwnProperty.call(t, e)), o = i.filter((t) => !Object.prototype.hasOwnProperty.call(e, t));
|
|
435
600
|
if (a.length > 0 || o.length > 0) {
|
|
436
601
|
let e = [];
|
|
437
602
|
throw a.length > 0 && e.push(`missing in second operand: [${a.join(", ")}]`), o.length > 0 && e.push(`missing in first operand: [${o.join(", ")}]`), Error(`Key mismatch in dot() at '${n || "root"}': ${e.join("; ")}.`);
|
|
@@ -442,45 +607,207 @@ function ee(e, t) {
|
|
|
442
607
|
throw Error(`Unsupported operand types in dot() at '${n || "root"}'.`);
|
|
443
608
|
}
|
|
444
609
|
c(e, t);
|
|
445
|
-
for (let [e, t] of n)
|
|
610
|
+
for (let [e, t] of n) t === 0 && n.delete(e);
|
|
446
611
|
return new C(n, r);
|
|
447
612
|
}
|
|
448
613
|
//#endregion
|
|
614
|
+
//#region src/modeler/validation.ts
|
|
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);
|
|
620
|
+
(r !== t || i !== t) && (n && n.push(() => {
|
|
621
|
+
e.ownerModel = r, i ? D.set(e, i) : D.delete(e);
|
|
622
|
+
}), e.ownerModel = t, D.set(e, t));
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
function ee(e, t) {
|
|
626
|
+
let n = E.get(e);
|
|
627
|
+
if (n && n !== t) throw Error(`Variable "${e.name}" already belongs to model "${n.name}" and cannot be added to model "${t.name}".`);
|
|
628
|
+
E.set(e, t);
|
|
629
|
+
}
|
|
630
|
+
function te(e, t) {
|
|
631
|
+
let n = O.get(e);
|
|
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}".`);
|
|
633
|
+
let r = D.get(e);
|
|
634
|
+
if (r && r !== t) throw Error(`Constraint "${e.name}" already belongs to model "${r.name}" and cannot be added to model "${t.name}".`);
|
|
635
|
+
return O.set(e, t), D.set(e, t), r;
|
|
636
|
+
}
|
|
637
|
+
function ne(e, t) {
|
|
638
|
+
E.get(e) === t && E.delete(e);
|
|
639
|
+
}
|
|
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));
|
|
642
|
+
}
|
|
643
|
+
var ie = 1e-6;
|
|
644
|
+
function A(e) {
|
|
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).`);
|
|
646
|
+
if (e.lb === Infinity) throw Error(`Variable "${e.name}" has invalid lower bound: +Infinity is not allowed as a lower bound.`);
|
|
647
|
+
if (typeof e.ub != "number" || Number.isNaN(e.ub)) throw Error(`Variable "${e.name}" has invalid upper bound: ${e.ub} (NaN or non-numeric bound is not allowed).`);
|
|
648
|
+
if (e.ub === -Infinity) throw Error(`Variable "${e.name}" has invalid upper bound: -Infinity is not allowed as an upper bound.`);
|
|
649
|
+
if (e.lb > e.ub) throw Error(`Variable "${e.name}" has invalid bounds: lower bound (${e.lb}) is strictly greater than upper bound (${e.ub}).`);
|
|
650
|
+
if (e.initialValue !== void 0) {
|
|
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).`);
|
|
652
|
+
let t = e.type === "Binary" ? Math.max(0, e.lb) : e.lb, n = e.type === "Binary" ? Math.min(1, e.ub) : e.ub;
|
|
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}).`);
|
|
654
|
+
if (e.type === "Integer" || e.type === "Binary") {
|
|
655
|
+
let r = Math.round(e.initialValue);
|
|
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}]).`);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
function ae(e) {
|
|
661
|
+
if (e.initialValue === void 0) return;
|
|
662
|
+
if (A(e), e.type === "Integer" || e.type === "Binary") {
|
|
663
|
+
let t = Math.round(e.initialValue);
|
|
664
|
+
return Object.is(t, -0) ? 0 : t;
|
|
665
|
+
}
|
|
666
|
+
let t = Math.min(e.ub, Math.max(e.lb, e.initialValue));
|
|
667
|
+
return Object.is(t, -0) ? 0 : t;
|
|
668
|
+
}
|
|
669
|
+
function oe(e, t, n) {
|
|
670
|
+
if (e instanceof S) {
|
|
671
|
+
if (!Number.isFinite(e.constant)) throw Error(`Objective function has invalid constant: ${e.constant}. Constant must be a finite number.`);
|
|
672
|
+
for (let [r, i] of e.linearTerms) {
|
|
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.`);
|
|
674
|
+
if (!Number.isFinite(i)) throw Error(`Variable "${r.name}" in objective function has invalid coefficient: ${i}. Coefficients must be finite numbers.`);
|
|
675
|
+
}
|
|
676
|
+
for (let [, r] of e.quadTerms) {
|
|
677
|
+
if (!n(r.var1)) throw Error(`Variable "${r.var1.name}" in quadratic objective function does not belong to model "${t}". All variables must belong to the model by object identity.`);
|
|
678
|
+
if (!n(r.var2)) throw Error(`Variable "${r.var2.name}" in quadratic objective function does not belong to model "${t}". All variables must belong to the model by object identity.`);
|
|
679
|
+
if (!Number.isFinite(r.coeff) || !Number.isFinite(r.coeff * 2)) throw Error(`Quadratic term (${r.var1.name} * ${r.var2.name}) in objective function has invalid coefficient: ${r.coeff}.`);
|
|
680
|
+
}
|
|
681
|
+
} else if ("terms" in e) {
|
|
682
|
+
if (!Number.isFinite(e.constant)) throw Error(`Objective function has invalid constant: ${e.constant}. Constant must be a finite number.`);
|
|
683
|
+
for (let [r, i] of e.terms) {
|
|
684
|
+
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.`);
|
|
685
|
+
if (!Number.isFinite(i)) throw Error(`Variable "${r.name}" in objective function has invalid coefficient: ${i}. Coefficients must be finite numbers.`);
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
function j(e, t, n, r = e.name) {
|
|
690
|
+
if (!Number.isFinite(e.rhs)) throw Error(`Constraint "${r}" has invalid right-hand side (RHS): ${e.rhs}. RHS must be a finite number.`);
|
|
691
|
+
if (e.lhs.constant !== void 0 && !Number.isFinite(e.lhs.constant)) throw Error(`Constraint "${r}" has invalid LHS constant: ${e.lhs.constant}. Constant must be a finite number.`);
|
|
692
|
+
for (let [i, a] of e.lhs.terms) {
|
|
693
|
+
if (!n(i)) throw Error(`Variable "${i.name}" in constraint "${r}" does not belong to model "${t}". All variables must belong to the model by object identity.`);
|
|
694
|
+
if (!Number.isFinite(a)) throw Error(`Variable "${i.name}" in constraint "${r}" has invalid coefficient: ${a}. Coefficients must be finite numbers.`);
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
function se(e, t, n, r, i, a) {
|
|
698
|
+
if (e instanceof d) {
|
|
699
|
+
if (!i(e)) throw Error(`Boolean variable "${e.name}" in logical constraint "${t}" does not belong to model "${n}".`);
|
|
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) {
|
|
702
|
+
if (a) {
|
|
703
|
+
let r = D.get(e) ?? e.ownerModel ?? void 0;
|
|
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}".`);
|
|
705
|
+
}
|
|
706
|
+
if (!Number.isFinite(e.rhs)) throw Error(`Constraint "${e.name}" embedded in logical constraint "${t}" has invalid RHS: ${e.rhs}.`);
|
|
707
|
+
if (e.lhs.constant !== void 0 && !Number.isFinite(e.lhs.constant)) throw Error(`Constraint "${e.name}" embedded in logical constraint "${t}" has invalid LHS constant: ${e.lhs.constant}.`);
|
|
708
|
+
for (let [i, a] of e.lhs.terms) {
|
|
709
|
+
if (!r(i)) throw Error(`Variable "${i.name}" embedded in logical constraint "${t}" does not belong to model "${n}".`);
|
|
710
|
+
if (!Number.isFinite(a)) throw Error(`Variable "${i.name}" embedded in logical constraint "${t}" has invalid coefficient: ${a}.`);
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
function ce(e) {
|
|
715
|
+
let t = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new Set();
|
|
716
|
+
for (let r of e.variables) {
|
|
717
|
+
A(r);
|
|
718
|
+
let i = E.get(r);
|
|
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}".`);
|
|
720
|
+
t.add(r.name), n.add(r);
|
|
721
|
+
}
|
|
722
|
+
let r = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set();
|
|
723
|
+
for (let t of e.boolVars) {
|
|
724
|
+
if (r.has(t.name) || e.getBoolVarByName(t.name) !== t) throw Error(`Boolean variable "${t.name}" is duplicated or not canonically registered in model "${e.name}".`);
|
|
725
|
+
r.add(t.name), i.add(t);
|
|
726
|
+
}
|
|
727
|
+
let a = /* @__PURE__ */ new Set();
|
|
728
|
+
for (let t of e.constraints) {
|
|
729
|
+
if (r.has(t.name)) throw Error(`Constraint name "${t.name}" conflicts with Boolean variable "${t.name}" in model "${e.name}".`);
|
|
730
|
+
if (a.has(t.name)) throw Error(`Duplicate constraint name "${t.name}" in model "${e.name}".`);
|
|
731
|
+
a.add(t.name);
|
|
732
|
+
}
|
|
733
|
+
for (let t of e.logicalConstraints) {
|
|
734
|
+
if (r.has(t.name)) throw Error(`Logical constraint name "${t.name}" conflicts with Boolean variable "${t.name}" in model "${e.name}".`);
|
|
735
|
+
if (a.has(t.name)) throw Error(`Conflicting constraint name "${t.name}" across arithmetic and logical constraints in model "${e.name}".`);
|
|
736
|
+
a.add(t.name);
|
|
737
|
+
}
|
|
738
|
+
for (let t of e.constraints) {
|
|
739
|
+
let n = D.get(t);
|
|
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}".`);
|
|
741
|
+
}
|
|
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}".`);
|
|
743
|
+
e.objectiveExpr && oe(e.objectiveExpr, e.name, (e) => n.has(e));
|
|
744
|
+
for (let t of e.constraints) j(t, e.name, (e) => n.has(e));
|
|
745
|
+
for (let t of e.logicalConstraints) se(t.expr, t.name, e.name, (e) => n.has(e), (e) => i.has(e), e);
|
|
746
|
+
}
|
|
747
|
+
//#endregion
|
|
449
748
|
//#region src/modeler/variable.ts
|
|
450
|
-
var
|
|
451
|
-
function
|
|
452
|
-
if (
|
|
453
|
-
|
|
454
|
-
|
|
749
|
+
var le = 0;
|
|
750
|
+
function ue(e) {
|
|
751
|
+
if (e === void 0) return "Continuous";
|
|
752
|
+
if (typeof e == "string") {
|
|
753
|
+
let t = e.toLowerCase();
|
|
754
|
+
if (t === "binary" || t === "bin") return "Binary";
|
|
755
|
+
if (t === "integer" || t === "int") return "Integer";
|
|
756
|
+
if (t === "continuous" || t === "cont") return "Continuous";
|
|
757
|
+
}
|
|
758
|
+
throw Error(`Invalid variable type "${String(e)}": expected "Continuous", "Integer", or "Binary".`);
|
|
455
759
|
}
|
|
456
|
-
var
|
|
760
|
+
var M = class {
|
|
457
761
|
id;
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
762
|
+
_name;
|
|
763
|
+
prefix;
|
|
764
|
+
hasExplicitName;
|
|
765
|
+
ownerModel = null;
|
|
766
|
+
_type;
|
|
767
|
+
_lb;
|
|
768
|
+
_ub;
|
|
769
|
+
_initialValue;
|
|
462
770
|
value = null;
|
|
463
771
|
reducedCost = null;
|
|
464
772
|
constructor(e = {}) {
|
|
465
|
-
this.id = ++
|
|
773
|
+
this.id = ++le;
|
|
774
|
+
let t = typeof e.name == "string" ? e.name.trim() : "", n = typeof e.prefix == "string" ? e.prefix.trim() : "";
|
|
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);
|
|
466
776
|
}
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
777
|
+
get name() {
|
|
778
|
+
return this._name;
|
|
779
|
+
}
|
|
780
|
+
get type() {
|
|
781
|
+
return this._type;
|
|
782
|
+
}
|
|
783
|
+
set type(e) {
|
|
784
|
+
let t = ue(e);
|
|
785
|
+
this._type !== t && (this._type = t, this.ownerModel?.notifyMutation?.());
|
|
786
|
+
}
|
|
787
|
+
get lb() {
|
|
788
|
+
return this._lb;
|
|
789
|
+
}
|
|
790
|
+
set lb(e) {
|
|
791
|
+
Object.is(this._lb, e) || (this._lb = e, this.ownerModel?.notifyMutation?.());
|
|
792
|
+
}
|
|
793
|
+
get ub() {
|
|
794
|
+
return this._ub;
|
|
795
|
+
}
|
|
796
|
+
set ub(e) {
|
|
797
|
+
Object.is(this._ub, e) || (this._ub = e, this.ownerModel?.notifyMutation?.());
|
|
798
|
+
}
|
|
799
|
+
get initialValue() {
|
|
800
|
+
return this._initialValue;
|
|
801
|
+
}
|
|
802
|
+
set initialValue(e) {
|
|
803
|
+
let t = e !== void 0 && Object.is(e, -0) ? 0 : e;
|
|
804
|
+
Object.is(this._initialValue, t) || (this._initialValue = t, this.ownerModel?.notifyMutation?.());
|
|
805
|
+
}
|
|
806
|
+
_assignModelName(e) {
|
|
807
|
+
this._name = e;
|
|
808
|
+
}
|
|
809
|
+
mul(e) {
|
|
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);
|
|
484
811
|
}
|
|
485
812
|
add(e) {
|
|
486
813
|
return e instanceof S ? e.add(this) : new C(/* @__PURE__ */ new Map([[this, 1]]), 0).add(e);
|
|
@@ -494,108 +821,100 @@ var D = class e {
|
|
|
494
821
|
le(e, t) {
|
|
495
822
|
return new C(/* @__PURE__ */ new Map([[this, 1]]), 0).le(e, t);
|
|
496
823
|
}
|
|
497
|
-
lessThanOrEqual(e, t) {
|
|
498
|
-
return this.le(e, t);
|
|
499
|
-
}
|
|
500
824
|
ge(e, t) {
|
|
501
825
|
return new C(/* @__PURE__ */ new Map([[this, 1]]), 0).ge(e, t);
|
|
502
826
|
}
|
|
503
|
-
greaterThanOrEqual(e, t) {
|
|
504
|
-
return this.ge(e, t);
|
|
505
|
-
}
|
|
506
827
|
eq(e, t) {
|
|
507
828
|
return new C(/* @__PURE__ */ new Map([[this, 1]]), 0).eq(e, t);
|
|
508
829
|
}
|
|
509
|
-
equalTo(e, t) {
|
|
510
|
-
return this.eq(e, t);
|
|
511
|
-
}
|
|
512
830
|
toString() {
|
|
513
831
|
return this.name;
|
|
514
832
|
}
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
if (/\s/.test(i)) {
|
|
523
|
-
n++;
|
|
833
|
+
}, de = /^(?:[0-9]+(?:\.[0-9]+)?|\.[0-9]+)(?:[eE][+-]?[0-9]+)?$/;
|
|
834
|
+
function fe(e, t) {
|
|
835
|
+
let n = [], r = 0, i = e.length;
|
|
836
|
+
for (; r < i;) {
|
|
837
|
+
let a = e[r];
|
|
838
|
+
if (/\s/.test(a)) {
|
|
839
|
+
r++;
|
|
524
840
|
continue;
|
|
525
841
|
}
|
|
526
|
-
if (
|
|
842
|
+
if (a === "+") n.push({
|
|
527
843
|
type: "PLUS",
|
|
528
844
|
value: "+"
|
|
529
|
-
}),
|
|
530
|
-
else if (
|
|
845
|
+
}), r++;
|
|
846
|
+
else if (a === "-") n.push({
|
|
531
847
|
type: "MINUS",
|
|
532
848
|
value: "-"
|
|
533
|
-
}),
|
|
534
|
-
else if (
|
|
849
|
+
}), r++;
|
|
850
|
+
else if (a === "*") r + 1 < i && e[r + 1] === "*" ? (n.push({
|
|
535
851
|
type: "CARET",
|
|
536
852
|
value: "**"
|
|
537
|
-
}),
|
|
853
|
+
}), r += 2) : (n.push({
|
|
538
854
|
type: "STAR",
|
|
539
855
|
value: "*"
|
|
540
|
-
}),
|
|
541
|
-
else if (
|
|
856
|
+
}), r++);
|
|
857
|
+
else if (a === "^") n.push({
|
|
542
858
|
type: "CARET",
|
|
543
859
|
value: "^"
|
|
544
|
-
}),
|
|
545
|
-
else if (
|
|
860
|
+
}), r++;
|
|
861
|
+
else if (a === "/") n.push({
|
|
546
862
|
type: "SLASH",
|
|
547
863
|
value: "/"
|
|
548
|
-
}),
|
|
549
|
-
else if (
|
|
864
|
+
}), r++;
|
|
865
|
+
else if (a === "(") n.push({
|
|
550
866
|
type: "LPAREN",
|
|
551
867
|
value: "("
|
|
552
|
-
}),
|
|
553
|
-
else if (
|
|
868
|
+
}), r++;
|
|
869
|
+
else if (a === ")") n.push({
|
|
554
870
|
type: "RPAREN",
|
|
555
871
|
value: ")"
|
|
556
|
-
}),
|
|
557
|
-
else if (
|
|
558
|
-
let
|
|
559
|
-
|
|
872
|
+
}), r++;
|
|
873
|
+
else if (a === "<" || a === ">" || a === "=") {
|
|
874
|
+
let t = a;
|
|
875
|
+
r + 1 < i && (e[r + 1] === "=" || e[r + 1] === "<" || e[r + 1] === ">") ? (t += e[r + 1], r += 2) : r++, n.push({
|
|
560
876
|
type: "COMP",
|
|
561
|
-
value:
|
|
877
|
+
value: t
|
|
562
878
|
});
|
|
563
|
-
} else if (/[0-9.]/.test(
|
|
564
|
-
let
|
|
565
|
-
for (;
|
|
566
|
-
|
|
879
|
+
} else if (/[0-9.]/.test(a)) {
|
|
880
|
+
let t = r, a = "";
|
|
881
|
+
for (; r < i && /[0-9]/.test(e[r]);) a += e[r++];
|
|
882
|
+
if (r < i && e[r] === ".") for (a += e[r++]; r < i && /[0-9]/.test(e[r]);) a += e[r++];
|
|
883
|
+
if (r < i && (e[r] === "e" || e[r] === "E")) {
|
|
884
|
+
let t = r + 1 < i ? e[r + 1] : "";
|
|
885
|
+
if (!/[a-zA-Z_]/.test(t)) {
|
|
886
|
+
for (a += e[r++], r < i && (e[r] === "+" || e[r] === "-") && (a += e[r++]); r < i && /[0-9]/.test(e[r]);) a += e[r++];
|
|
887
|
+
for (; r < i && (e[r] === "." || e[r] === "e" || e[r] === "E" || /[0-9]/.test(e[r]));) a += e[r++];
|
|
888
|
+
}
|
|
889
|
+
} else for (; r < i && (e[r] === "." || /[0-9]/.test(e[r]));) a += e[r++];
|
|
890
|
+
if (!de.test(a)) throw Error(`Invalid numeric literal '${a}' at position ${t} in: "${e}"`);
|
|
891
|
+
let o = Number(a);
|
|
892
|
+
if (!Number.isFinite(o)) throw Error(`Numeric literal '${a}' overflows finite floating-point range in: "${e}"`);
|
|
893
|
+
if (o === 0 && !/^[0.]+(?:[eE][+-]?\d+)?$/.test(a)) throw Error(`Numeric literal '${a}' underflows to zero at position ${t} in: "${e}"`);
|
|
894
|
+
n.push({
|
|
567
895
|
type: "NUMBER",
|
|
568
|
-
value:
|
|
896
|
+
value: a,
|
|
897
|
+
numericValue: o
|
|
569
898
|
});
|
|
570
|
-
} else if (/[a-zA-Z_]/.test(
|
|
571
|
-
let
|
|
572
|
-
for (;
|
|
573
|
-
t.
|
|
899
|
+
} else if (/[a-zA-Z_]/.test(a)) {
|
|
900
|
+
let a = "";
|
|
901
|
+
for (; r < i && /[a-zA-Z0-9_]/.test(e[r]);) a += e[r], r++;
|
|
902
|
+
if (t && t.has(a)) {
|
|
903
|
+
let e = t.get(a);
|
|
904
|
+
n.push({
|
|
905
|
+
type: "NUMBER",
|
|
906
|
+
value: String(e),
|
|
907
|
+
numericValue: e
|
|
908
|
+
});
|
|
909
|
+
} else n.push({
|
|
574
910
|
type: "IDENT",
|
|
575
|
-
value:
|
|
911
|
+
value: a
|
|
576
912
|
});
|
|
577
|
-
} else throw Error(`Unexpected character '${
|
|
913
|
+
} else throw Error(`Unexpected character '${a}' at position ${r} in: "${e}"`);
|
|
578
914
|
}
|
|
579
|
-
return
|
|
580
|
-
}
|
|
581
|
-
function k(e, t) {
|
|
582
|
-
return e instanceof S ? e.add(t) : t instanceof S ? t.add(e) : e.add(t);
|
|
583
|
-
}
|
|
584
|
-
function te(e, t) {
|
|
585
|
-
return e instanceof S ? e.sub(t) : t instanceof S ? t.neg().add(e) : e.sub(t);
|
|
586
|
-
}
|
|
587
|
-
function A(e, t) {
|
|
588
|
-
let n = e instanceof S ? e.quadTerms : /* @__PURE__ */ new Map(), r = t instanceof S ? t.quadTerms : /* @__PURE__ */ new Map(), i = e instanceof S ? e.linearTerms : e.terms, a = t instanceof S ? t.linearTerms : t.terms;
|
|
589
|
-
if (n.size > 0 && (r.size > 0 || a.size > 0) || r.size > 0 && (n.size > 0 || i.size > 0)) throw Error("Multiplication creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)");
|
|
590
|
-
if (n.size === 0 && i.size === 0) return t.mul(e.constant);
|
|
591
|
-
if (r.size === 0 && a.size === 0) return e.mul(t.constant);
|
|
592
|
-
let o = new S();
|
|
593
|
-
if (o.constant = e.constant * t.constant, Math.abs(t.constant) >= 1e-12) for (let [e, n] of i) o.linearTerms.set(e, (o.linearTerms.get(e) || 0) + n * t.constant);
|
|
594
|
-
if (Math.abs(e.constant) >= 1e-12) for (let [t, n] of a) o.linearTerms.set(t, (o.linearTerms.get(t) || 0) + n * e.constant);
|
|
595
|
-
for (let [e, t] of i) for (let [n, r] of a) o = o.add(S.fromProduct(e, n, t * r));
|
|
596
|
-
return o;
|
|
915
|
+
return n;
|
|
597
916
|
}
|
|
598
|
-
var
|
|
917
|
+
var pe = class {
|
|
599
918
|
tokens;
|
|
600
919
|
pos = 0;
|
|
601
920
|
resolver;
|
|
@@ -616,8 +935,8 @@ var j = class {
|
|
|
616
935
|
for (; this.pos < this.tokens.length;) {
|
|
617
936
|
let t = this.peek();
|
|
618
937
|
if (!t) break;
|
|
619
|
-
if (t.type === "PLUS") this.consume(), e =
|
|
620
|
-
else if (t.type === "MINUS") this.consume(), e =
|
|
938
|
+
if (t.type === "PLUS") this.consume(), e = e.add(this.parseTerm());
|
|
939
|
+
else if (t.type === "MINUS") this.consume(), e = e.sub(this.parseTerm());
|
|
621
940
|
else break;
|
|
622
941
|
}
|
|
623
942
|
return e instanceof S && e.quadTerms.size === 0 ? new C(e.linearTerms, e.constant) : e;
|
|
@@ -627,17 +946,9 @@ var j = class {
|
|
|
627
946
|
for (; this.pos < this.tokens.length;) {
|
|
628
947
|
let t = this.peek();
|
|
629
948
|
if (!t) break;
|
|
630
|
-
if (t.type === "STAR")
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
e = A(e, t);
|
|
634
|
-
} else if (t.type === "SLASH") {
|
|
635
|
-
this.consume();
|
|
636
|
-
let t = this.parseFactor(), n = t instanceof S ? t.linearTerms : t.terms, r = t instanceof S ? t.quadTerms.size : 0;
|
|
637
|
-
if (n.size > 0 || r > 0) throw Error("Cannot divide by variable in expression");
|
|
638
|
-
if (Math.abs(t.constant) < 1e-12) throw Error("Division by zero in expression");
|
|
639
|
-
e = e.div(t.constant);
|
|
640
|
-
} else break;
|
|
949
|
+
if (t.type === "STAR") this.consume(), e = e.mul(this.parseFactor());
|
|
950
|
+
else if (t.type === "SLASH") this.consume(), e = e.div(this.parseFactor());
|
|
951
|
+
else break;
|
|
641
952
|
}
|
|
642
953
|
return e;
|
|
643
954
|
}
|
|
@@ -649,12 +960,12 @@ var j = class {
|
|
|
649
960
|
let t;
|
|
650
961
|
if (e.type === "NUMBER") {
|
|
651
962
|
this.consume();
|
|
652
|
-
let n =
|
|
963
|
+
let n = e.numericValue ?? Number(e.value);
|
|
653
964
|
if (this.peek()?.type === "IDENT" || this.peek()?.type === "LPAREN") {
|
|
654
965
|
let e;
|
|
655
966
|
if (this.peek()?.type === "IDENT") {
|
|
656
967
|
let t = this.consume(), n = this.resolve(t.value);
|
|
657
|
-
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();
|
|
658
969
|
} else this.consume("LPAREN"), e = this.parseExpression(), this.consume("RPAREN");
|
|
659
970
|
return this.applyPower(e).mul(n);
|
|
660
971
|
}
|
|
@@ -662,7 +973,7 @@ var j = class {
|
|
|
662
973
|
} else if (e.type === "IDENT") {
|
|
663
974
|
this.consume();
|
|
664
975
|
let n = this.resolve(e.value);
|
|
665
|
-
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();
|
|
666
977
|
} else if (e.type === "LPAREN") this.consume("LPAREN"), t = this.parseExpression(), this.consume("RPAREN");
|
|
667
978
|
else throw Error(`Unexpected token '${e.value}' in expression`);
|
|
668
979
|
return this.applyPower(t);
|
|
@@ -672,12 +983,14 @@ var j = class {
|
|
|
672
983
|
let t = [];
|
|
673
984
|
for (; this.peek()?.type === "CARET";) {
|
|
674
985
|
this.consume();
|
|
675
|
-
let e = this.
|
|
676
|
-
|
|
677
|
-
this.
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
986
|
+
let e = this.tokens[this.pos]?.type === "LPAREN" && this.tokens[this.pos + 1]?.type === "NUMBER" && this.tokens[this.pos + 2]?.type === "RPAREN";
|
|
987
|
+
e && this.consume("LPAREN");
|
|
988
|
+
let n = this.peek();
|
|
989
|
+
if (!n || n.type !== "NUMBER") throw Error("Exponent must be a non-negative integer number");
|
|
990
|
+
this.consume(), e && this.consume("RPAREN");
|
|
991
|
+
let r = n.numericValue ?? Number(n.value);
|
|
992
|
+
if (!Number.isInteger(r) || r < 0) throw Error("Exponent must be a non-negative integer");
|
|
993
|
+
t.push(r);
|
|
681
994
|
}
|
|
682
995
|
let n = t[t.length - 1];
|
|
683
996
|
for (let e = t.length - 2; e >= 0; e--) n = t[e] ** +n;
|
|
@@ -685,11 +998,12 @@ var j = class {
|
|
|
685
998
|
let r = e instanceof S, i = r ? e.quadTerms.size : 0, a = r ? e.linearTerms.size : e.terms.size;
|
|
686
999
|
if (i === 0 && a === 0) {
|
|
687
1000
|
let t = e.constant ** +n;
|
|
1001
|
+
if (e.constant !== 0 && n > 0 && t === 0) throw Error("Constant exponentiation underflows to zero.");
|
|
688
1002
|
return new C(/* @__PURE__ */ new Map(), t);
|
|
689
1003
|
}
|
|
690
1004
|
if (n === 0) return new C(/* @__PURE__ */ new Map(), 1);
|
|
691
1005
|
if (n === 1) return e;
|
|
692
|
-
if (n === 2) return
|
|
1006
|
+
if (n === 2) return e.mul(e);
|
|
693
1007
|
throw Error(`Exponent ${n} creates a non-linear term of degree > 2 (not allowed in MILP/LP/QP)`);
|
|
694
1008
|
}
|
|
695
1009
|
getRemainingToken() {
|
|
@@ -701,159 +1015,221 @@ var j = class {
|
|
|
701
1015
|
return t;
|
|
702
1016
|
}
|
|
703
1017
|
};
|
|
704
|
-
function M(e, t) {
|
|
705
|
-
let n = new j(O(e), t), r = n.parseExpression(), i = n.getRemainingToken();
|
|
706
|
-
if (i) throw Error(`Unexpected token '${i.value}' after expression in "${e}"`);
|
|
707
|
-
return r;
|
|
708
|
-
}
|
|
709
1018
|
function N(e, t, n) {
|
|
710
|
-
let r = e.
|
|
711
|
-
if (
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
1019
|
+
let r = new pe(fe(e, n), t), i = r.parseExpression(), a = r.getRemainingToken();
|
|
1020
|
+
if (a) throw Error(`Unexpected token '${a.value}' after expression in "${e}"`);
|
|
1021
|
+
return P(i), i;
|
|
1022
|
+
}
|
|
1023
|
+
function me(e, t) {
|
|
1024
|
+
return N(e, t);
|
|
1025
|
+
}
|
|
1026
|
+
function he(e, t, n, r) {
|
|
1027
|
+
let i = e.match(/(<=|>=|==|=<|=>|=)/);
|
|
1028
|
+
if (!i) throw Error(`Constraint must contain a comparison operator (<=, >=, ==, =): "${e}"`);
|
|
1029
|
+
let a = i[0], o = i.index, s = e.substring(0, o).trim(), c = e.substring(o + a.length).trim(), l;
|
|
1030
|
+
if (a === "<=" || a === "=<") l = "<=";
|
|
1031
|
+
else if (a === ">=" || a === "=>") l = ">=";
|
|
1032
|
+
else if (a === "==" || a === "=") l = "==";
|
|
1033
|
+
else throw Error(`Unsupported operator "${a}"`);
|
|
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.`);
|
|
1038
|
+
return m;
|
|
1039
|
+
}
|
|
1040
|
+
function ge(e, t, n) {
|
|
1041
|
+
return he(e, t, n);
|
|
1042
|
+
}
|
|
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";
|
|
1045
|
+
}
|
|
1046
|
+
function P(e) {
|
|
1047
|
+
if ("constant" in e && !Number.isFinite(e.constant)) throw Error(`Invalid non-finite constant "${e.constant}" in expression.`);
|
|
1048
|
+
if ("terms" in e && e.terms instanceof Map) {
|
|
1049
|
+
for (let [, t] of e.terms) if (!Number.isFinite(t)) throw Error(`Invalid non-finite coefficient "${t}" in expression.`);
|
|
1050
|
+
}
|
|
1051
|
+
if ("linearTerms" in e && e.linearTerms instanceof Map) {
|
|
1052
|
+
for (let [, t] of e.linearTerms) if (!Number.isFinite(t)) throw Error(`Invalid non-finite coefficient "${t}" in expression.`);
|
|
1053
|
+
}
|
|
1054
|
+
if ("quadTerms" in e && e.quadTerms instanceof Map) {
|
|
1055
|
+
for (let [, t] of e.quadTerms) if (!Number.isFinite(t.coeff)) throw Error(`Invalid non-finite quadratic coefficient "${t.coeff}" in expression.`);
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
function ve(e) {
|
|
1059
|
+
return e instanceof y || typeof e == "object" && !!e && "sense" in e && "lhs" in e && "rhs" in e;
|
|
1060
|
+
}
|
|
1061
|
+
function ye(e, t) {
|
|
1062
|
+
let n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map(), i = e.join(""), a = "__washi_";
|
|
1063
|
+
for (; i.includes(a);) a += "_";
|
|
1064
|
+
let o = "";
|
|
1065
|
+
for (let i = 0; i < e.length; i++) if (o += e[i], i < t.length) {
|
|
725
1066
|
let e = t[i];
|
|
726
|
-
if (typeof e == "number")
|
|
727
|
-
|
|
728
|
-
let t =
|
|
729
|
-
|
|
730
|
-
}
|
|
1067
|
+
if (typeof e == "number") {
|
|
1068
|
+
if (!Number.isFinite(e)) throw Error(`Invalid numeric value "${e}" in template expression: interpolated numbers must be finite.`);
|
|
1069
|
+
let t = `${a}num_${i}__`;
|
|
1070
|
+
r.set(t, e), o += `(${t})`;
|
|
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);
|
|
1074
|
+
let t = `${a}ph_${i}__`;
|
|
1075
|
+
n.set(t, e), o += ` ${t} `;
|
|
1076
|
+
} else throw Error("Unsupported interpolation value in template expression: expected a finite number, Var, LinExpr, or QuadExpr.");
|
|
731
1077
|
}
|
|
732
1078
|
return {
|
|
733
|
-
fullText:
|
|
734
|
-
resolver: (e) => n.get(e)
|
|
1079
|
+
fullText: o,
|
|
1080
|
+
resolver: (e) => n.get(e),
|
|
1081
|
+
numberMap: r
|
|
735
1082
|
};
|
|
736
1083
|
}
|
|
737
|
-
function
|
|
738
|
-
let { fullText: n, resolver: r } =
|
|
739
|
-
return N(n, r);
|
|
740
|
-
}
|
|
741
|
-
function I(e, ...t) {
|
|
742
|
-
let { fullText: n, resolver: r } = P(e, t);
|
|
743
|
-
return /(<=|>=|==|=<|=>|=)/.test(n) ? N(n, r) : M(n, r);
|
|
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);
|
|
744
1087
|
}
|
|
745
1088
|
//#endregion
|
|
746
1089
|
//#region src/modeler/lp-writer.ts
|
|
747
|
-
function
|
|
1090
|
+
function F(e) {
|
|
1091
|
+
return typeof e == "object" && !!e && typeof e.lpString == "string" && e.nameToVar instanceof Map && e.nameToConstraint instanceof Map;
|
|
1092
|
+
}
|
|
1093
|
+
function I(e, t = "x", n = 0) {
|
|
748
1094
|
let r = e.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
749
1095
|
return /^[0-9]/.test(r) && (r = `${t}_${r}`), (!r || r.length === 0) && (r = `${t}_${n}`), r;
|
|
750
1096
|
}
|
|
751
|
-
function
|
|
752
|
-
let
|
|
753
|
-
for (let e
|
|
754
|
-
let
|
|
755
|
-
|
|
756
|
-
|
|
1097
|
+
function xe(e) {
|
|
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();
|
|
1099
|
+
for (let e = 0; e < t.length; e++) {
|
|
1100
|
+
let n = t[e];
|
|
1101
|
+
s.set(n, e);
|
|
1102
|
+
let a = I(n.name, "x", e), o = a, l = 1;
|
|
1103
|
+
for (; c.has(o);) o = `${a}_${l++}`;
|
|
1104
|
+
c.add(o), i.set(n, o), r.set(o, n);
|
|
1105
|
+
}
|
|
1106
|
+
let l = /* @__PURE__ */ new Set();
|
|
1107
|
+
for (let e = 0; e < n.length; e++) {
|
|
1108
|
+
let t = n[e], r = I(t.name, "c", e + 1), i = r, s = 1;
|
|
1109
|
+
for (; l.has(i);) i = `${r}_${s++}`;
|
|
1110
|
+
l.add(i), o.set(t, i), a.set(i, t);
|
|
757
1111
|
}
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
let e =
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
1112
|
+
return {
|
|
1113
|
+
nameToVar: r,
|
|
1114
|
+
varToName: i,
|
|
1115
|
+
nameToConstraint: a,
|
|
1116
|
+
constraintToName: o,
|
|
1117
|
+
constrToName: o,
|
|
1118
|
+
varOrder: s
|
|
1119
|
+
};
|
|
1120
|
+
}
|
|
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) {
|
|
1126
|
+
if (t === 0) continue;
|
|
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;
|
|
1129
|
+
}
|
|
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 ? [
|
|
1133
|
+
e.var1,
|
|
1134
|
+
e.var2,
|
|
1135
|
+
t,
|
|
1136
|
+
n
|
|
1137
|
+
] : [
|
|
1138
|
+
e.var2,
|
|
1139
|
+
e.var1,
|
|
1140
|
+
n,
|
|
1141
|
+
t
|
|
1142
|
+
];
|
|
1143
|
+
return {
|
|
1144
|
+
firstVar: r,
|
|
1145
|
+
secondVar: i,
|
|
1146
|
+
firstIdx: a,
|
|
1147
|
+
secondIdx: o,
|
|
1148
|
+
coeff: e.coeff
|
|
1149
|
+
};
|
|
1150
|
+
}).sort((e, t) => e.firstIdx - t.firstIdx || e.secondIdx - t.secondIdx);
|
|
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;
|
|
778
1154
|
}
|
|
779
1155
|
if (e.length > 0) {
|
|
780
1156
|
let t = `[ ${e.join(" ")} ] / 2`;
|
|
781
|
-
|
|
1157
|
+
p.length > 0 ? p.push("+", t) : p.push(t);
|
|
782
1158
|
}
|
|
783
1159
|
}
|
|
784
|
-
let
|
|
785
|
-
|
|
786
|
-
for (let e of
|
|
1160
|
+
let g = p.length > 0 ? p.join(" ") : "0";
|
|
1161
|
+
f.push(` obj: ${g}`), f.push("Subject To");
|
|
1162
|
+
for (let e of i) {
|
|
787
1163
|
let t = u.get(e), n = [], r = !0;
|
|
788
1164
|
for (let [t, i] of e.lhs.terms) {
|
|
789
|
-
if (
|
|
790
|
-
let e =
|
|
791
|
-
n.push(`${a}${
|
|
1165
|
+
if (i === 0) continue;
|
|
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;
|
|
792
1168
|
}
|
|
793
1169
|
let i = n.length > 0 ? n.join(" ") : "0", a = e.sense === "==" ? "=" : e.sense;
|
|
794
|
-
|
|
795
|
-
}
|
|
796
|
-
|
|
797
|
-
let
|
|
798
|
-
for (let e of
|
|
799
|
-
let t =
|
|
800
|
-
if (e.type === "Binary") {
|
|
801
|
-
|
|
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);
|
|
802
1178
|
continue;
|
|
803
1179
|
}
|
|
804
|
-
e.type === "Integer" &&
|
|
1180
|
+
!o && e.type === "Integer" && _.push(t);
|
|
805
1181
|
let n = e.lb === -Infinity, r = e.ub === Infinity;
|
|
806
|
-
n && r ?
|
|
807
|
-
}
|
|
808
|
-
if (g.length > 0) {
|
|
809
|
-
d.push("Generals");
|
|
810
|
-
for (let e = 0; e < g.length; e += 10) d.push(" " + g.slice(e, e + 10).join(" "));
|
|
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}`);
|
|
811
1183
|
}
|
|
812
1184
|
if (_.length > 0) {
|
|
813
|
-
|
|
814
|
-
for (let e = 0; e < _.length; e += 10)
|
|
1185
|
+
f.push("Generals");
|
|
1186
|
+
for (let e = 0; e < _.length; e += 10) f.push(" " + _.slice(e, e + 10).join(" "));
|
|
1187
|
+
}
|
|
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(" "));
|
|
815
1191
|
}
|
|
816
|
-
return
|
|
817
|
-
lpString:
|
|
818
|
-
nameToVar:
|
|
819
|
-
nameToConstraint:
|
|
1192
|
+
return f.push("End"), {
|
|
1193
|
+
lpString: f.join("\n") + "\n",
|
|
1194
|
+
nameToVar: s,
|
|
1195
|
+
nameToConstraint: l
|
|
820
1196
|
};
|
|
821
1197
|
}
|
|
822
1198
|
//#endregion
|
|
823
1199
|
//#region src/modeler/solvers/registry.ts
|
|
824
|
-
var
|
|
825
|
-
|
|
826
|
-
var
|
|
827
|
-
function
|
|
828
|
-
|
|
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) {
|
|
1204
|
+
B.set(e.toLowerCase(), t);
|
|
829
1205
|
}
|
|
830
|
-
function
|
|
1206
|
+
function we(e) {
|
|
831
1207
|
if (typeof e == "string") {
|
|
832
|
-
let t =
|
|
1208
|
+
let t = B.get(e.toLowerCase());
|
|
833
1209
|
if (!t) throw Error(`Solver '${e}' is not registered.`);
|
|
834
|
-
|
|
835
|
-
} else
|
|
1210
|
+
z[Se] = t;
|
|
1211
|
+
} else z[Se] = typeof e == "function" ? e : () => e;
|
|
836
1212
|
}
|
|
837
|
-
function
|
|
1213
|
+
function V(e, t) {
|
|
838
1214
|
if (!e) {
|
|
839
|
-
let e =
|
|
840
|
-
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(", ")}`);
|
|
841
1217
|
return e(t);
|
|
842
1218
|
}
|
|
843
1219
|
if (typeof e == "string") {
|
|
844
|
-
let n = e.toLowerCase(), r =
|
|
845
|
-
if (!r) throw Error(n === "glpk" ? `Solver 'glpk' not found. Available solvers: ${
|
|
1220
|
+
let n = e.toLowerCase(), r = B.get(n);
|
|
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(", ")}`);
|
|
846
1222
|
return r(t);
|
|
847
1223
|
}
|
|
848
1224
|
return e;
|
|
849
1225
|
}
|
|
850
|
-
function
|
|
851
|
-
return Array.from(
|
|
1226
|
+
function H() {
|
|
1227
|
+
return Array.from(B.keys());
|
|
852
1228
|
}
|
|
853
1229
|
//#endregion
|
|
854
1230
|
//#region \0washi-browser-worker-factory
|
|
855
|
-
function
|
|
856
|
-
let e =
|
|
1231
|
+
function Te() {
|
|
1232
|
+
let e = a("highs-worker.js");
|
|
857
1233
|
if (new URL(e).origin === window.location.origin) return new Worker(e, { type: "module" });
|
|
858
1234
|
let t = URL.createObjectURL(new Blob(["import " + JSON.stringify(e) + ";"], { type: "text/javascript" }));
|
|
859
1235
|
try {
|
|
@@ -865,73 +1241,198 @@ function q() {
|
|
|
865
1241
|
}
|
|
866
1242
|
//#endregion
|
|
867
1243
|
//#region src/modeler/solvers/highs/worker-client.ts
|
|
868
|
-
var
|
|
869
|
-
function
|
|
1244
|
+
var U = null, Ee = 0, W = /* @__PURE__ */ new Map();
|
|
1245
|
+
function De(e, t) {
|
|
1246
|
+
return e ? {
|
|
1247
|
+
Status: "Interrupted",
|
|
1248
|
+
StatusCode: 17,
|
|
1249
|
+
HasPrimalSolution: !0,
|
|
1250
|
+
IsMip: !0,
|
|
1251
|
+
ObjectiveValue: e.objectiveValue,
|
|
1252
|
+
ObjectiveOffsetApplied: !0,
|
|
1253
|
+
...t?.objectiveBound === void 0 ? e.mipDualBound === void 0 ? {} : { MipDualBound: e.mipDualBound } : { MipDualBound: t.objectiveBound },
|
|
1254
|
+
...t?.relGap === void 0 ? e.mipGap === void 0 ? {} : { MipGap: e.mipGap } : { MipGap: t.relGap },
|
|
1255
|
+
Columns: e.columns,
|
|
1256
|
+
Rows: []
|
|
1257
|
+
} : {
|
|
1258
|
+
Status: "Interrupted",
|
|
1259
|
+
StatusCode: 17,
|
|
1260
|
+
HasPrimalSolution: !1,
|
|
1261
|
+
ObjectiveValue: NaN,
|
|
1262
|
+
ObjectiveOffsetApplied: !0,
|
|
1263
|
+
...t?.objectiveBound === void 0 ? {} : { MipDualBound: t.objectiveBound },
|
|
1264
|
+
...t?.relGap === void 0 ? {} : { MipGap: t.relGap },
|
|
1265
|
+
Columns: {},
|
|
1266
|
+
Rows: []
|
|
1267
|
+
};
|
|
1268
|
+
}
|
|
1269
|
+
function G(e) {
|
|
1270
|
+
let t = W.values().next().value;
|
|
1271
|
+
if (t && !t.dispatched) {
|
|
1272
|
+
t.dispatched = !0;
|
|
1273
|
+
try {
|
|
1274
|
+
e.postMessage({
|
|
1275
|
+
type: "SOLVE",
|
|
1276
|
+
id: t.id,
|
|
1277
|
+
lpString: t.lpString,
|
|
1278
|
+
options: t.workerOptions,
|
|
1279
|
+
...t.reportProgress ? { reportProgress: !0 } : {}
|
|
1280
|
+
});
|
|
1281
|
+
} catch (n) {
|
|
1282
|
+
W.delete(t.id), t.cleanupAbort?.(), t.reject(n), G(e);
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
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);
|
|
1293
|
+
else {
|
|
1294
|
+
let e = /* @__PURE__ */ Error("[WaSHI] Failed to recreate HiGHS Worker after interruption.");
|
|
1295
|
+
for (let t of Array.from(W.values())) W.delete(t.id), t.cleanupAbort?.(), t.reject(e);
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
function ke() {
|
|
870
1300
|
if (typeof window > "u" || typeof Worker > "u") return null;
|
|
871
|
-
if (!
|
|
872
|
-
|
|
873
|
-
let e =
|
|
874
|
-
|
|
875
|
-
let { type:
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
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);
|
|
1306
|
+
if (l) {
|
|
1307
|
+
if (n === "SOLVE_PROGRESS") {
|
|
1308
|
+
if (s) {
|
|
1309
|
+
l.lastProgress = s;
|
|
1310
|
+
try {
|
|
1311
|
+
l.onProgress?.(s);
|
|
1312
|
+
} catch (e) {
|
|
1313
|
+
let t = W.get(r);
|
|
1314
|
+
if (t) {
|
|
1315
|
+
let n = W.keys().next().value;
|
|
1316
|
+
W.delete(r), t.cleanupAbort?.(), n === r && Oe(), t.reject(e);
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
return;
|
|
1321
|
+
}
|
|
1322
|
+
if (n === "SOLVE_INCUMBENT") {
|
|
1323
|
+
c && (l.lastIncumbent = c);
|
|
1324
|
+
return;
|
|
1325
|
+
}
|
|
1326
|
+
W.delete(r), l.cleanupAbort?.(), n === "SOLVE_SUCCESS" ? l.resolve({
|
|
1327
|
+
result: i,
|
|
1328
|
+
runTime: a
|
|
1329
|
+
}) : l.reject(Error(o || "Worker solve failed")), U === e && G(e);
|
|
1330
|
+
}
|
|
880
1331
|
};
|
|
881
1332
|
let t = (t) => {
|
|
882
|
-
if (
|
|
883
|
-
|
|
884
|
-
for (let e of
|
|
885
|
-
|
|
1333
|
+
if (U === e) {
|
|
1334
|
+
U = null, e.terminate();
|
|
1335
|
+
for (let e of W.values()) e.cleanupAbort?.(), e.reject(t);
|
|
1336
|
+
W.clear();
|
|
886
1337
|
}
|
|
887
1338
|
};
|
|
888
|
-
|
|
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."));
|
|
889
1340
|
} catch {
|
|
890
|
-
|
|
891
|
-
}
|
|
892
|
-
return
|
|
893
|
-
}
|
|
894
|
-
async function
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
1341
|
+
U = null;
|
|
1342
|
+
}
|
|
1343
|
+
return U;
|
|
1344
|
+
}
|
|
1345
|
+
async function Ae(t, n = {}) {
|
|
1346
|
+
if (n.signal?.aborted) return {
|
|
1347
|
+
result: De(),
|
|
1348
|
+
runTime: 0
|
|
1349
|
+
};
|
|
1350
|
+
let r = await i(n.wasmUrl);
|
|
1351
|
+
if (n.signal?.aborted) return {
|
|
1352
|
+
result: De(),
|
|
1353
|
+
runTime: 0
|
|
1354
|
+
};
|
|
1355
|
+
let a = n.useWorker ?? typeof window < "u" ? ke() : null;
|
|
1356
|
+
if (!a) return e(t, n);
|
|
1357
|
+
let { signal: o, onProgress: s, ...c } = n, l = {};
|
|
1358
|
+
for (let [e, t] of Object.entries(c)) typeof t != "function" && (l[e] = t);
|
|
1359
|
+
l.wasmUrl = r;
|
|
1360
|
+
let u = !!(s || o), d = `req_${++Ee}`, f = performance.now();
|
|
1361
|
+
return new Promise((e, n) => {
|
|
1362
|
+
let r = {
|
|
1363
|
+
id: d,
|
|
1364
|
+
lpString: t,
|
|
1365
|
+
workerOptions: l,
|
|
1366
|
+
reportProgress: u,
|
|
1367
|
+
startTime: f,
|
|
1368
|
+
onProgress: s,
|
|
1369
|
+
resolve: e,
|
|
904
1370
|
reject: n
|
|
905
|
-
}
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
1371
|
+
};
|
|
1372
|
+
if (o) {
|
|
1373
|
+
let e = () => {
|
|
1374
|
+
let e = W.get(d);
|
|
1375
|
+
if (!e) return;
|
|
1376
|
+
let t = W.keys().next().value;
|
|
1377
|
+
W.delete(d), e.cleanupAbort?.(), t === d && Oe();
|
|
1378
|
+
let n = (performance.now() - e.startTime) / 1e3;
|
|
1379
|
+
e.resolve({
|
|
1380
|
+
result: De(e.lastIncumbent, e.lastProgress),
|
|
1381
|
+
runTime: n
|
|
1382
|
+
});
|
|
1383
|
+
};
|
|
1384
|
+
o.addEventListener("abort", e, { once: !0 }), r.cleanupAbort = () => o.removeEventListener("abort", e);
|
|
915
1385
|
}
|
|
1386
|
+
W.set(d, r), G(a);
|
|
916
1387
|
});
|
|
917
1388
|
}
|
|
918
1389
|
//#endregion
|
|
919
1390
|
//#region src/modeler/solvers/highs/solver.ts
|
|
920
|
-
function
|
|
1391
|
+
function je(e, t) {
|
|
1392
|
+
if (typeof t == "number") switch (t) {
|
|
1393
|
+
case 0: return "NotSolved";
|
|
1394
|
+
case 1:
|
|
1395
|
+
case 2:
|
|
1396
|
+
case 3:
|
|
1397
|
+
case 4:
|
|
1398
|
+
case 5: return "Error";
|
|
1399
|
+
case 6: return "Unknown";
|
|
1400
|
+
case 7: return "Optimal";
|
|
1401
|
+
case 8: return "Infeasible";
|
|
1402
|
+
case 9: return "InfeasibleOrUnbounded";
|
|
1403
|
+
case 10: return "Unbounded";
|
|
1404
|
+
case 11: return "ObjectiveBound";
|
|
1405
|
+
case 12: return "ObjectiveTarget";
|
|
1406
|
+
case 13: return "TimeLimit";
|
|
1407
|
+
case 14: return "IterationLimit";
|
|
1408
|
+
case 15: return "Unknown";
|
|
1409
|
+
case 16: return "SolutionLimit";
|
|
1410
|
+
case 17: return "Interrupted";
|
|
1411
|
+
case 18: return "MemoryLimit";
|
|
1412
|
+
}
|
|
921
1413
|
if (typeof e != "string") return "Unknown";
|
|
922
|
-
let
|
|
923
|
-
if (!
|
|
924
|
-
switch (
|
|
1414
|
+
let n = e.trim();
|
|
1415
|
+
if (!n) return "Unknown";
|
|
1416
|
+
switch (n) {
|
|
925
1417
|
case "Optimal": return "Optimal";
|
|
926
1418
|
case "Infeasible": return "Infeasible";
|
|
927
1419
|
case "Unbounded": return "Unbounded";
|
|
928
|
-
case "Primal infeasible or unbounded":
|
|
1420
|
+
case "Primal infeasible or unbounded":
|
|
1421
|
+
case "InfeasibleOrUnbounded": return "InfeasibleOrUnbounded";
|
|
929
1422
|
case "Time limit reached":
|
|
930
1423
|
case "TimeLimit": return "TimeLimit";
|
|
931
1424
|
case "Iteration limit reached":
|
|
932
1425
|
case "IterationLimit": return "IterationLimit";
|
|
1426
|
+
case "Solution limit reached":
|
|
1427
|
+
case "SolutionLimit": return "SolutionLimit";
|
|
1428
|
+
case "Memory limit reached":
|
|
1429
|
+
case "MemoryLimit": return "MemoryLimit";
|
|
933
1430
|
case "Bound on objective reached":
|
|
1431
|
+
case "ObjectiveBound": return "ObjectiveBound";
|
|
934
1432
|
case "Target for objective reached":
|
|
1433
|
+
case "ObjectiveTarget": return "ObjectiveTarget";
|
|
1434
|
+
case "Interrupted":
|
|
1435
|
+
case "User interrupt": return "Interrupted";
|
|
935
1436
|
case "Feasible": return "Feasible";
|
|
936
1437
|
case "Not Set": return "NotSolved";
|
|
937
1438
|
case "Load error":
|
|
@@ -943,136 +1444,1314 @@ function re(e) {
|
|
|
943
1444
|
case "Empty":
|
|
944
1445
|
case "Unknown": return "Unknown";
|
|
945
1446
|
}
|
|
946
|
-
let
|
|
947
|
-
return
|
|
1447
|
+
let r = n.toLowerCase();
|
|
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";
|
|
1449
|
+
}
|
|
1450
|
+
function Me(e, t, n) {
|
|
1451
|
+
switch (je(e, t)) {
|
|
1452
|
+
case "Optimal": return "Optimal";
|
|
1453
|
+
case "Infeasible": return "Infeasible";
|
|
1454
|
+
case "Unbounded": return "Unbounded";
|
|
1455
|
+
case "TimeLimit": return "TimeLimit";
|
|
1456
|
+
case "IterationLimit": return "IterationLimit";
|
|
1457
|
+
case "Feasible": return "Feasible";
|
|
1458
|
+
case "ObjectiveBound":
|
|
1459
|
+
case "ObjectiveTarget":
|
|
1460
|
+
case "SolutionLimit": return n === !1 ? "Unknown" : "Feasible";
|
|
1461
|
+
case "MemoryLimit":
|
|
1462
|
+
case "Interrupted": return n ? "Feasible" : "Unknown";
|
|
1463
|
+
case "NotSolved": return "NotSolved";
|
|
1464
|
+
case "Error": return "Error";
|
|
1465
|
+
default: return "Unknown";
|
|
1466
|
+
}
|
|
948
1467
|
}
|
|
949
|
-
var
|
|
1468
|
+
var K = class e {
|
|
950
1469
|
static capabilities = {
|
|
951
1470
|
supportsMIP: !0,
|
|
952
|
-
supportsQP: !0
|
|
1471
|
+
supportsQP: !0,
|
|
1472
|
+
supportsWarmStart: !0
|
|
953
1473
|
};
|
|
954
1474
|
name = "HiGHS";
|
|
955
|
-
version = "1.15.
|
|
1475
|
+
version = "1.15.1";
|
|
956
1476
|
capabilities = e.capabilities;
|
|
957
1477
|
options;
|
|
958
1478
|
constructor(e = {}) {
|
|
959
1479
|
this.options = e;
|
|
960
1480
|
}
|
|
961
|
-
async solve(e, t, n = {}) {
|
|
962
|
-
let r = {
|
|
1481
|
+
async solve(e, t = {}, n = {}) {
|
|
1482
|
+
let r = F(t), i = r ? n : t, a = {
|
|
963
1483
|
...this.options,
|
|
964
|
-
...
|
|
965
|
-
},
|
|
966
|
-
|
|
967
|
-
|
|
1484
|
+
...i
|
|
1485
|
+
}, o = e.objective.constant || 0;
|
|
1486
|
+
for (let t of e.variables) A(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();
|
|
1488
|
+
for (let [e, t] of c.entries()) {
|
|
1489
|
+
f.add(t);
|
|
1490
|
+
let n = ae(t);
|
|
1491
|
+
n !== void 0 && (u[e] = n, d = !0);
|
|
1492
|
+
}
|
|
1493
|
+
for (let t = 0; t < e.variables.length; t++) {
|
|
1494
|
+
let n = e.variables[t];
|
|
1495
|
+
if (!f.has(n)) {
|
|
1496
|
+
let e = ae(n);
|
|
1497
|
+
if (e !== void 0) {
|
|
1498
|
+
let r = I(n.name, "x", t);
|
|
1499
|
+
Object.prototype.hasOwnProperty.call(u, r) || (u[r] = e, d = !0);
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
let p = a;
|
|
1504
|
+
(o !== 0 || d || p.initialValues !== void 0) && (p = {
|
|
1505
|
+
...p,
|
|
1506
|
+
...o === 0 ? {} : { objectiveOffset: o },
|
|
1507
|
+
initialValues: d ? u : void 0
|
|
1508
|
+
});
|
|
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;
|
|
1510
|
+
if (typeof m?.HasPrimalSolution == "boolean") y = m.HasPrimalSolution;
|
|
1511
|
+
else {
|
|
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);
|
|
1513
|
+
y = _ === "Infeasible" || _ === "Unbounded" || _ === "InfeasibleOrUnbounded" || _ === "Error" || _ === "NotSolved" ? !1 : _ === "Optimal" || _ === "Feasible" ? n || t : n && (e.length === 0 || t);
|
|
1514
|
+
}
|
|
1515
|
+
let b = Me(m?.Status, m?.StatusCode, y), x = null;
|
|
1516
|
+
y && typeof m?.ObjectiveValue == "number" && Number.isFinite(m.ObjectiveValue) && (x = m.ObjectiveValue + g);
|
|
1517
|
+
let S, C, w;
|
|
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) {
|
|
1519
|
+
if (w === 0) C = 0;
|
|
1520
|
+
else if (Math.abs(x) > 0) {
|
|
1521
|
+
let e = w / Math.abs(x);
|
|
1522
|
+
C = Number.isFinite(e) ? e : void 0;
|
|
1523
|
+
} else C = void 0;
|
|
1524
|
+
} else typeof m?.MipGap == "number" && Number.isFinite(m.MipGap) ? C = m.MipGap : v && _ === "Optimal" && y && (w === void 0 || w === 0) && (C = 0);
|
|
1525
|
+
if (!y) return {
|
|
1526
|
+
status: b,
|
|
1527
|
+
terminationStatus: _,
|
|
1528
|
+
hasPrimalSolution: !1,
|
|
968
1529
|
objectiveValue: null,
|
|
1530
|
+
...S === void 0 ? {} : { objectiveBound: S },
|
|
1531
|
+
...C === void 0 ? {} : {
|
|
1532
|
+
relGap: C,
|
|
1533
|
+
mipGap: C
|
|
1534
|
+
},
|
|
1535
|
+
...w === void 0 ? {} : { absGap: w },
|
|
969
1536
|
values: {},
|
|
970
1537
|
reducedCosts: {},
|
|
971
1538
|
duals: {},
|
|
972
1539
|
slacks: {},
|
|
973
|
-
runTime:
|
|
974
|
-
raw:
|
|
1540
|
+
runTime: h,
|
|
1541
|
+
raw: m
|
|
975
1542
|
};
|
|
976
|
-
let
|
|
977
|
-
|
|
978
|
-
|
|
1543
|
+
let T = (e, t, n) => {
|
|
1544
|
+
Object.defineProperty(e, t, {
|
|
1545
|
+
value: n,
|
|
1546
|
+
enumerable: !0,
|
|
1547
|
+
writable: !0,
|
|
1548
|
+
configurable: !0
|
|
1549
|
+
});
|
|
1550
|
+
}, E = {}, D = {}, O = {}, k = {};
|
|
1551
|
+
if (m.Columns) for (let [e, t] of Object.entries(m.Columns)) {
|
|
1552
|
+
let n = c.get(e);
|
|
979
1553
|
if (n) {
|
|
980
|
-
|
|
981
|
-
|
|
1554
|
+
if (typeof t.Primal == "number" && Number.isFinite(t.Primal)) {
|
|
1555
|
+
let e = Math.abs(t.Primal) < 1e-9 ? 0 : t.Primal;
|
|
1556
|
+
T(E, n.name, e);
|
|
1557
|
+
}
|
|
1558
|
+
typeof t.Dual == "number" && Number.isFinite(t.Dual) && T(O, n.name, Math.abs(t.Dual) < 1e-9 ? 0 : t.Dual);
|
|
982
1559
|
}
|
|
983
1560
|
}
|
|
984
|
-
if (
|
|
985
|
-
let e = Array.isArray(
|
|
1561
|
+
if (m.Rows) {
|
|
1562
|
+
let e = Array.isArray(m.Rows) ? m.Rows : Object.values(m.Rows);
|
|
986
1563
|
for (let t of e) {
|
|
987
|
-
let e = t.Name, n =
|
|
988
|
-
if (n && (t.Dual
|
|
1564
|
+
let e = t.Name, n = e ? l.get(e) : void 0;
|
|
1565
|
+
if (n && (typeof t.Dual == "number" && Number.isFinite(t.Dual) && T(D, n.name, Math.abs(t.Dual) < 1e-9 ? 0 : t.Dual), typeof t.Primal == "number" && Number.isFinite(t.Primal))) {
|
|
989
1566
|
let e = n.rhs - t.Primal;
|
|
990
|
-
|
|
1567
|
+
T(k, n.name, Math.abs(e) < 1e-9 ? 0 : e);
|
|
991
1568
|
}
|
|
992
1569
|
}
|
|
993
1570
|
}
|
|
994
1571
|
return {
|
|
995
|
-
status:
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1572
|
+
status: b,
|
|
1573
|
+
terminationStatus: _,
|
|
1574
|
+
hasPrimalSolution: !0,
|
|
1575
|
+
objectiveValue: x,
|
|
1576
|
+
...S === void 0 ? {} : { objectiveBound: S },
|
|
1577
|
+
...C === void 0 ? {} : {
|
|
1578
|
+
relGap: C,
|
|
1579
|
+
mipGap: C
|
|
1580
|
+
},
|
|
1581
|
+
...w === void 0 ? {} : { absGap: w },
|
|
1582
|
+
values: E,
|
|
1583
|
+
reducedCosts: O,
|
|
1584
|
+
duals: D,
|
|
1585
|
+
slacks: k,
|
|
1586
|
+
runTime: h,
|
|
1587
|
+
raw: m
|
|
1003
1588
|
};
|
|
1004
1589
|
}
|
|
1005
|
-
},
|
|
1006
|
-
function
|
|
1007
|
-
|
|
1590
|
+
}, Ne = K;
|
|
1591
|
+
function Pe() {
|
|
1592
|
+
Ce("highs", (e) => new K(e)), we((e) => new K(e));
|
|
1008
1593
|
}
|
|
1009
|
-
|
|
1594
|
+
Pe();
|
|
1010
1595
|
//#endregion
|
|
1011
1596
|
//#region src/modeler/solvers/mock.ts
|
|
1012
|
-
var
|
|
1597
|
+
var Fe = class {
|
|
1013
1598
|
name;
|
|
1014
1599
|
capabilities;
|
|
1015
1600
|
options;
|
|
1016
1601
|
constructor(e = {}) {
|
|
1017
1602
|
this.name = e.name || "MockSolver", this.capabilities = e.capabilities || {
|
|
1018
1603
|
supportsMIP: !0,
|
|
1019
|
-
supportsQP: !0
|
|
1604
|
+
supportsQP: !0,
|
|
1605
|
+
supportsWarmStart: !0
|
|
1020
1606
|
}, this.options = e;
|
|
1021
1607
|
}
|
|
1022
|
-
async solve(e, t, n = {}) {
|
|
1023
|
-
let r = {
|
|
1608
|
+
async solve(e, t = {}, n = {}) {
|
|
1609
|
+
let r = F(t) ? n : t, i = {
|
|
1024
1610
|
...this.options,
|
|
1025
|
-
...
|
|
1611
|
+
...r
|
|
1612
|
+
}, a = !!(i.values && Object.keys(i.values).length > 0 || i.boolValues && Object.keys(i.boolValues).length > 0);
|
|
1613
|
+
if (i.signal?.aborted) return {
|
|
1614
|
+
status: "Unknown",
|
|
1615
|
+
terminationStatus: "Interrupted",
|
|
1616
|
+
hasPrimalSolution: !1,
|
|
1617
|
+
objectiveValue: null,
|
|
1618
|
+
values: {},
|
|
1619
|
+
runTime: 0,
|
|
1620
|
+
raw: { mock: !0 }
|
|
1026
1621
|
};
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1622
|
+
if (i.delayMs && i.delayMs > 0 && (await new Promise((e) => {
|
|
1623
|
+
let t = setTimeout(() => {
|
|
1624
|
+
i.signal?.removeEventListener("abort", n), e();
|
|
1625
|
+
}, i.delayMs), n = () => {
|
|
1626
|
+
clearTimeout(t), e();
|
|
1627
|
+
};
|
|
1628
|
+
i.signal?.addEventListener("abort", n, { once: !0 });
|
|
1629
|
+
}), i.signal?.aborted)) {
|
|
1630
|
+
let e = !!(i.hasPrimalSolution ?? a);
|
|
1631
|
+
return {
|
|
1632
|
+
status: e ? "Feasible" : "Unknown",
|
|
1633
|
+
terminationStatus: "Interrupted",
|
|
1634
|
+
hasPrimalSolution: e,
|
|
1635
|
+
objectiveValue: e ? i.objectiveValue ?? 0 : null,
|
|
1636
|
+
...i.objectiveBound === void 0 ? {} : { objectiveBound: i.objectiveBound },
|
|
1637
|
+
...i.relGap === void 0 ? i.mipGap === void 0 ? {} : {
|
|
1638
|
+
relGap: i.mipGap,
|
|
1639
|
+
mipGap: i.mipGap
|
|
1640
|
+
} : {
|
|
1641
|
+
relGap: i.relGap,
|
|
1642
|
+
mipGap: i.relGap
|
|
1643
|
+
},
|
|
1644
|
+
...i.absGap === void 0 ? {} : { absGap: i.absGap },
|
|
1645
|
+
values: e && i.values || {},
|
|
1646
|
+
...e && i.boolValues !== void 0 ? { boolValues: i.boolValues } : {},
|
|
1647
|
+
runTime: .001,
|
|
1648
|
+
raw: { mock: !0 }
|
|
1649
|
+
};
|
|
1650
|
+
}
|
|
1651
|
+
if (i.onProgress && Array.isArray(i.progressEvents)) for (let e of i.progressEvents) {
|
|
1652
|
+
if (i.signal?.aborted) break;
|
|
1653
|
+
i.onProgress(e);
|
|
1654
|
+
}
|
|
1655
|
+
let o = i.status || "Optimal", s = i.terminationStatus ?? o, c = i.hasPrimalSolution === void 0 ? o === "Optimal" || o === "Feasible" || o === "Sat" || (o === "TimeLimit" || o === "IterationLimit" || s === "Interrupted") && a : i.hasPrimalSolution;
|
|
1656
|
+
if (i.onProgress && !Array.isArray(i.progressEvents) && !i.signal?.aborted) {
|
|
1657
|
+
let e = c ? i.objectiveValue ?? 0 : void 0;
|
|
1658
|
+
i.onProgress({
|
|
1659
|
+
elapsedTime: .001,
|
|
1660
|
+
elapsedSeconds: .001,
|
|
1661
|
+
...typeof e == "number" && Number.isFinite(e) ? { objectiveValue: e } : {},
|
|
1662
|
+
...i.objectiveBound === void 0 ? {} : { objectiveBound: i.objectiveBound },
|
|
1663
|
+
...i.relGap === void 0 ? i.mipGap === void 0 ? {} : {
|
|
1664
|
+
relGap: i.mipGap,
|
|
1665
|
+
mipGap: i.mipGap
|
|
1666
|
+
} : {
|
|
1667
|
+
relGap: i.relGap,
|
|
1668
|
+
mipGap: i.relGap
|
|
1669
|
+
},
|
|
1670
|
+
...i.absGap === void 0 ? {} : { absGap: i.absGap }
|
|
1671
|
+
});
|
|
1672
|
+
}
|
|
1673
|
+
return i.signal?.aborted && (s = "Interrupted", c = i.hasPrimalSolution === void 0 ? a : i.hasPrimalSolution, o = c ? "Feasible" : "Unknown"), {
|
|
1674
|
+
status: o,
|
|
1675
|
+
terminationStatus: s,
|
|
1676
|
+
hasPrimalSolution: c,
|
|
1677
|
+
objectiveValue: c ? i.objectiveValue ?? 0 : null,
|
|
1678
|
+
...i.objectiveBound === void 0 ? {} : { objectiveBound: i.objectiveBound },
|
|
1679
|
+
...i.relGap === void 0 ? i.mipGap === void 0 ? {} : {
|
|
1680
|
+
relGap: i.mipGap,
|
|
1681
|
+
mipGap: i.mipGap
|
|
1682
|
+
} : {
|
|
1683
|
+
relGap: i.relGap,
|
|
1684
|
+
mipGap: i.relGap
|
|
1685
|
+
},
|
|
1686
|
+
...i.absGap === void 0 ? {} : { absGap: i.absGap },
|
|
1687
|
+
values: c && i.values || {},
|
|
1688
|
+
...c && i.boolValues !== void 0 ? { boolValues: i.boolValues } : {},
|
|
1689
|
+
reducedCosts: i.reducedCosts,
|
|
1690
|
+
duals: i.duals,
|
|
1691
|
+
slacks: i.slacks,
|
|
1034
1692
|
runTime: .001,
|
|
1035
1693
|
raw: { mock: !0 }
|
|
1036
1694
|
};
|
|
1037
1695
|
}
|
|
1038
1696
|
};
|
|
1039
|
-
function
|
|
1040
|
-
|
|
1697
|
+
function Ie() {
|
|
1698
|
+
Ce("mock", (e) => new Fe(e));
|
|
1041
1699
|
}
|
|
1042
|
-
|
|
1700
|
+
Ie();
|
|
1043
1701
|
//#endregion
|
|
1044
|
-
//#region src/modeler/
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1702
|
+
//#region src/modeler/solution-validator.ts
|
|
1703
|
+
function Le(e, t) {
|
|
1704
|
+
if (e === void 0) return 1e-6;
|
|
1705
|
+
if (typeof e != "number" || !Number.isFinite(e) || e < 0) throw Error(`Invalid ${t}: expected a finite non-negative number, received ${String(e)}.`);
|
|
1706
|
+
return e;
|
|
1707
|
+
}
|
|
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;
|
|
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.");
|
|
1711
|
+
let o = t.values, s = [], c = Object.create(null), l = [], u = [], p = 0, m = (e) => {
|
|
1712
|
+
typeof e == "number" && !Number.isNaN(e) && e > p && (p = e);
|
|
1713
|
+
}, h = (e) => {
|
|
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);
|
|
1715
|
+
}, g = /* @__PURE__ */ new Map(), _ = /* @__PURE__ */ new Map(), v = 0, b = 0, x = 0, S = 0;
|
|
1716
|
+
for (let t of e.variables) {
|
|
1717
|
+
let e = a ? Object.prototype.hasOwnProperty.call(o, t.name) ? o[t.name] : void 0 : t.value;
|
|
1718
|
+
if (e == null) {
|
|
1719
|
+
u.push(t.name), h({
|
|
1720
|
+
type: "missing_value",
|
|
1721
|
+
target: "variable",
|
|
1722
|
+
name: t.name,
|
|
1723
|
+
actual: e ?? null,
|
|
1724
|
+
violation: Infinity,
|
|
1725
|
+
message: `Variable "${t.name}" has no assigned solution value.`
|
|
1726
|
+
});
|
|
1727
|
+
continue;
|
|
1728
|
+
}
|
|
1729
|
+
if (typeof e != "number" || !Number.isFinite(e)) {
|
|
1730
|
+
h({
|
|
1731
|
+
type: "non_finite_value",
|
|
1732
|
+
target: "variable",
|
|
1733
|
+
name: t.name,
|
|
1734
|
+
actual: e,
|
|
1735
|
+
violation: Infinity,
|
|
1736
|
+
message: `Variable "${t.name}" has non-finite or non-numeric value: ${String(e)}.`
|
|
1737
|
+
});
|
|
1738
|
+
continue;
|
|
1739
|
+
}
|
|
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({
|
|
1743
|
+
type: "lower_bound",
|
|
1744
|
+
target: "variable",
|
|
1745
|
+
name: t.name,
|
|
1746
|
+
actual: e,
|
|
1747
|
+
limit: t.lb,
|
|
1748
|
+
violation: Infinity,
|
|
1749
|
+
message: `Variable "${t.name}" has invalid lower bound (${String(t.lb)}).`
|
|
1750
|
+
});
|
|
1751
|
+
else if (c !== -Infinity) {
|
|
1752
|
+
let r = e - c, i = Math.max(0, c - e);
|
|
1753
|
+
m(i), i > n && h({
|
|
1754
|
+
type: "lower_bound",
|
|
1755
|
+
target: "variable",
|
|
1756
|
+
name: t.name,
|
|
1757
|
+
actual: e,
|
|
1758
|
+
limit: c,
|
|
1759
|
+
violation: i,
|
|
1760
|
+
signedViolation: r,
|
|
1761
|
+
message: `Variable "${t.name}" value (${e}) violates lower bound (${c}) by ${i}.`
|
|
1762
|
+
});
|
|
1763
|
+
}
|
|
1764
|
+
if (!f) h({
|
|
1765
|
+
type: "upper_bound",
|
|
1766
|
+
target: "variable",
|
|
1767
|
+
name: t.name,
|
|
1768
|
+
actual: e,
|
|
1769
|
+
limit: t.ub,
|
|
1770
|
+
violation: Infinity,
|
|
1771
|
+
message: `Variable "${t.name}" has invalid upper bound (${String(t.ub)}).`
|
|
1772
|
+
});
|
|
1773
|
+
else if (l !== Infinity) {
|
|
1774
|
+
let r = e - l, i = Math.max(0, e - l);
|
|
1775
|
+
m(i), i > n && h({
|
|
1776
|
+
type: "upper_bound",
|
|
1777
|
+
target: "variable",
|
|
1778
|
+
name: t.name,
|
|
1779
|
+
actual: e,
|
|
1780
|
+
limit: l,
|
|
1781
|
+
violation: i,
|
|
1782
|
+
signedViolation: r,
|
|
1783
|
+
message: `Variable "${t.name}" value (${e}) violates upper bound (${l}) by ${i}.`
|
|
1784
|
+
});
|
|
1785
|
+
}
|
|
1786
|
+
if (d && f && c > l && c - e <= n && e - l <= n) {
|
|
1787
|
+
let n = c - l;
|
|
1788
|
+
h({
|
|
1789
|
+
type: "lower_bound",
|
|
1790
|
+
target: "variable",
|
|
1791
|
+
name: t.name,
|
|
1792
|
+
actual: e,
|
|
1793
|
+
limit: c,
|
|
1794
|
+
violation: n,
|
|
1795
|
+
signedViolation: e - c,
|
|
1796
|
+
message: `Variable "${t.name}" has inverted bounds [${c}, ${l}].`
|
|
1797
|
+
});
|
|
1798
|
+
}
|
|
1799
|
+
if (s) {
|
|
1800
|
+
let n = Math.round(e), a = e - n, o = Math.abs(a);
|
|
1801
|
+
m(o), o > r && h({
|
|
1802
|
+
type: "integrality",
|
|
1803
|
+
target: "variable",
|
|
1804
|
+
name: t.name,
|
|
1805
|
+
varType: i ? "Binary" : "Integer",
|
|
1806
|
+
actual: e,
|
|
1807
|
+
nearestInteger: n,
|
|
1808
|
+
violation: o,
|
|
1809
|
+
signedViolation: a,
|
|
1810
|
+
message: `${i ? "Binary" : "Integer"} variable "${t.name}" value (${e}) violates integrality by ${o} (nearest integer: ${n}).`
|
|
1811
|
+
});
|
|
1812
|
+
}
|
|
1813
|
+
}
|
|
1814
|
+
for (let t of e.boolVars) {
|
|
1815
|
+
let e = a ? Object.prototype.hasOwnProperty.call(o, t.name) ? o[t.name] : void 0 : t.value;
|
|
1816
|
+
if (e == null) {
|
|
1817
|
+
u.push(t.name), h({
|
|
1818
|
+
type: "missing_value",
|
|
1819
|
+
target: "bool_variable",
|
|
1820
|
+
name: t.name,
|
|
1821
|
+
actual: e ?? null,
|
|
1822
|
+
violation: Infinity,
|
|
1823
|
+
message: `Boolean variable "${t.name}" has no assigned solution value.`
|
|
1824
|
+
});
|
|
1825
|
+
continue;
|
|
1826
|
+
}
|
|
1827
|
+
if (typeof e != "boolean") {
|
|
1828
|
+
h({
|
|
1829
|
+
type: "invalid_boolean_value",
|
|
1830
|
+
target: "bool_variable",
|
|
1831
|
+
name: t.name,
|
|
1832
|
+
actual: e,
|
|
1833
|
+
violation: Infinity,
|
|
1834
|
+
message: `Boolean variable "${t.name}" has non-boolean value: ${String(e)}.`
|
|
1835
|
+
});
|
|
1836
|
+
continue;
|
|
1837
|
+
}
|
|
1838
|
+
_.set(t, e), b++;
|
|
1839
|
+
}
|
|
1840
|
+
let C = (e) => {
|
|
1841
|
+
let t = e.constant === void 0 ? 0 : e.constant;
|
|
1842
|
+
if (typeof t != "number" || !Number.isFinite(t)) return {
|
|
1843
|
+
ok: !1,
|
|
1844
|
+
reason: `non-finite constant (${String(t)})`
|
|
1845
|
+
};
|
|
1846
|
+
let n = t;
|
|
1847
|
+
for (let [t, r] of e.terms) {
|
|
1848
|
+
if (typeof r != "number" || !Number.isFinite(r)) return {
|
|
1849
|
+
ok: !1,
|
|
1850
|
+
reason: `non-finite coefficient (${String(r)}) for variable "${t.name}"`
|
|
1851
|
+
};
|
|
1852
|
+
if (r !== 0) {
|
|
1853
|
+
if (!g.has(t)) return {
|
|
1854
|
+
ok: !1,
|
|
1855
|
+
reason: `missing or invalid value for variable "${t.name}"`
|
|
1856
|
+
};
|
|
1857
|
+
if (n += r * g.get(t), !Number.isFinite(n)) return {
|
|
1858
|
+
ok: !1,
|
|
1859
|
+
reason: "linear expression evaluation overflowed finite range"
|
|
1860
|
+
};
|
|
1861
|
+
}
|
|
1862
|
+
}
|
|
1863
|
+
return {
|
|
1864
|
+
ok: !0,
|
|
1865
|
+
value: n
|
|
1866
|
+
};
|
|
1867
|
+
}, w = (e, t = n) => {
|
|
1868
|
+
if (typeof e.rhs != "number" || !Number.isFinite(e.rhs)) return {
|
|
1869
|
+
status: "unchecked",
|
|
1870
|
+
reason: `non-finite right-hand side (${String(e.rhs)})`
|
|
1871
|
+
};
|
|
1872
|
+
let r = C(e.lhs);
|
|
1873
|
+
if (!r.ok) return {
|
|
1874
|
+
status: "unchecked",
|
|
1875
|
+
reason: r.reason
|
|
1876
|
+
};
|
|
1877
|
+
let i = r.value, a = i - e.rhs;
|
|
1878
|
+
if (!Number.isFinite(a)) return {
|
|
1879
|
+
status: "unchecked",
|
|
1880
|
+
reason: "constraint residual overflowed finite range"
|
|
1881
|
+
};
|
|
1882
|
+
let o = e.sense === "<=" ? Math.max(0, a) : e.sense === ">=" ? Math.max(0, -a) : Math.abs(a);
|
|
1883
|
+
return o > t ? {
|
|
1884
|
+
status: "violated",
|
|
1885
|
+
lhsVal: i,
|
|
1886
|
+
signed: a,
|
|
1887
|
+
violation: o,
|
|
1888
|
+
message: `Constraint "${e.name}" (${i} ${e.sense} ${e.rhs}) violated by ${o}.`
|
|
1889
|
+
} : {
|
|
1890
|
+
status: "satisfied",
|
|
1891
|
+
lhsVal: i,
|
|
1892
|
+
signed: a,
|
|
1893
|
+
violation: o
|
|
1894
|
+
};
|
|
1895
|
+
};
|
|
1896
|
+
for (let t of e.constraints) {
|
|
1897
|
+
let e = w(t);
|
|
1898
|
+
e.status === "unchecked" ? (l.push(t.name), h({
|
|
1899
|
+
type: "unchecked_constraint",
|
|
1900
|
+
target: "constraint",
|
|
1901
|
+
name: t.name,
|
|
1902
|
+
sense: t.sense,
|
|
1903
|
+
limit: t.rhs,
|
|
1904
|
+
rhs: t.rhs,
|
|
1905
|
+
violation: Infinity,
|
|
1906
|
+
message: `Constraint "${t.name}" could not be evaluated: ${e.reason}.`
|
|
1907
|
+
})) : e.status === "violated" ? (x++, h({
|
|
1908
|
+
type: "linear_constraint",
|
|
1909
|
+
target: "constraint",
|
|
1910
|
+
name: t.name,
|
|
1911
|
+
sense: t.sense,
|
|
1912
|
+
actual: e.lhsVal,
|
|
1913
|
+
limit: t.rhs,
|
|
1914
|
+
rhs: t.rhs,
|
|
1915
|
+
violation: e.violation,
|
|
1916
|
+
signedViolation: e.signed,
|
|
1917
|
+
message: e.message
|
|
1918
|
+
})) : (x++, m(e.violation));
|
|
1919
|
+
}
|
|
1920
|
+
let T = (e) => {
|
|
1921
|
+
if (e instanceof d) return _.has(e) ? {
|
|
1922
|
+
ok: !0,
|
|
1923
|
+
value: _.get(e),
|
|
1924
|
+
violation: 0
|
|
1925
|
+
} : {
|
|
1926
|
+
ok: !1,
|
|
1927
|
+
reason: `missing or invalid value for Boolean variable "${e.name}"`
|
|
1928
|
+
};
|
|
1929
|
+
if (e instanceof y) {
|
|
1930
|
+
let t = w(e, 0);
|
|
1931
|
+
if (t.status === "unchecked") return {
|
|
1932
|
+
ok: !1,
|
|
1933
|
+
reason: t.reason
|
|
1934
|
+
};
|
|
1935
|
+
if (n > 0) {
|
|
1936
|
+
let r = Math.abs(t.lhsVal - e.rhs);
|
|
1937
|
+
if (r > 0 && r <= n) return {
|
|
1938
|
+
ok: !1,
|
|
1939
|
+
reason: `numeric comparison "${e.name}" lies within feasibilityTolerance (${n}) of boundary (${t.lhsVal} vs ${e.rhs})`
|
|
1940
|
+
};
|
|
1941
|
+
}
|
|
1942
|
+
return {
|
|
1943
|
+
ok: !0,
|
|
1944
|
+
value: t.status === "satisfied",
|
|
1945
|
+
violation: 0
|
|
1946
|
+
};
|
|
1947
|
+
}
|
|
1948
|
+
if (e instanceof f) switch (e.op) {
|
|
1949
|
+
case "not": {
|
|
1950
|
+
let t = T(e.children[0]);
|
|
1951
|
+
return t.ok ? {
|
|
1952
|
+
ok: !0,
|
|
1953
|
+
value: !t.value,
|
|
1954
|
+
violation: 0
|
|
1955
|
+
} : t;
|
|
1956
|
+
}
|
|
1957
|
+
case "and": {
|
|
1958
|
+
let t = 0;
|
|
1959
|
+
for (let n of e.children) {
|
|
1960
|
+
let e = T(n);
|
|
1961
|
+
if (!e.ok) return e;
|
|
1962
|
+
if (!e.value) return {
|
|
1963
|
+
ok: !0,
|
|
1964
|
+
value: !1,
|
|
1965
|
+
violation: 0
|
|
1966
|
+
};
|
|
1967
|
+
e.violation > t && (t = e.violation);
|
|
1968
|
+
}
|
|
1969
|
+
return {
|
|
1970
|
+
ok: !0,
|
|
1971
|
+
value: !0,
|
|
1972
|
+
violation: t
|
|
1973
|
+
};
|
|
1974
|
+
}
|
|
1975
|
+
case "or": {
|
|
1976
|
+
let t = !1, n = Infinity;
|
|
1977
|
+
for (let r of e.children) {
|
|
1978
|
+
let e = T(r);
|
|
1979
|
+
if (!e.ok) return e;
|
|
1980
|
+
e.value && (t = !0, e.violation < n && (n = e.violation));
|
|
1981
|
+
}
|
|
1982
|
+
return {
|
|
1983
|
+
ok: !0,
|
|
1984
|
+
value: t,
|
|
1985
|
+
violation: t ? n : 0
|
|
1986
|
+
};
|
|
1987
|
+
}
|
|
1988
|
+
case "implies": {
|
|
1989
|
+
let t = T(e.children[0]);
|
|
1990
|
+
if (!t.ok) return t;
|
|
1991
|
+
if (!t.value) return {
|
|
1992
|
+
ok: !0,
|
|
1993
|
+
value: !0,
|
|
1994
|
+
violation: 0
|
|
1995
|
+
};
|
|
1996
|
+
let n = T(e.children[1]);
|
|
1997
|
+
return n.ok ? {
|
|
1998
|
+
ok: !0,
|
|
1999
|
+
value: n.value,
|
|
2000
|
+
violation: n.value ? n.violation : 0
|
|
2001
|
+
} : n;
|
|
2002
|
+
}
|
|
2003
|
+
case "xor": {
|
|
2004
|
+
let t = !1, n = 0;
|
|
2005
|
+
for (let r of e.children) {
|
|
2006
|
+
let e = T(r);
|
|
2007
|
+
if (!e.ok) return e;
|
|
2008
|
+
e.value && (t = !t, e.violation > n && (n = e.violation));
|
|
2009
|
+
}
|
|
2010
|
+
return {
|
|
2011
|
+
ok: !0,
|
|
2012
|
+
value: t,
|
|
2013
|
+
violation: t ? n : 0
|
|
2014
|
+
};
|
|
2015
|
+
}
|
|
2016
|
+
default: return {
|
|
2017
|
+
ok: !1,
|
|
2018
|
+
reason: `unsupported logical operator "${String(e.op)}"`
|
|
2019
|
+
};
|
|
2020
|
+
}
|
|
2021
|
+
return {
|
|
2022
|
+
ok: !1,
|
|
2023
|
+
reason: "unsupported logical expression node"
|
|
2024
|
+
};
|
|
2025
|
+
};
|
|
2026
|
+
for (let t = 0; t < e.logicalConstraints.length; t++) {
|
|
2027
|
+
let n = e.logicalConstraints[t], r = n.name || `lc_${t + 1}`;
|
|
2028
|
+
if (!i) {
|
|
2029
|
+
l.push(r), h({
|
|
2030
|
+
type: "unchecked_constraint",
|
|
2031
|
+
target: "logical_constraint",
|
|
2032
|
+
name: r,
|
|
2033
|
+
violation: Infinity,
|
|
2034
|
+
message: `Logical constraint "${r}" was not evaluated because evaluateLogicalConstraints is false.`
|
|
2035
|
+
});
|
|
2036
|
+
continue;
|
|
2037
|
+
}
|
|
2038
|
+
let a = T(n.expr);
|
|
2039
|
+
if (!a.ok) {
|
|
2040
|
+
l.push(r), h({
|
|
2041
|
+
type: "unchecked_constraint",
|
|
2042
|
+
target: "logical_constraint",
|
|
2043
|
+
name: r,
|
|
2044
|
+
violation: Infinity,
|
|
2045
|
+
message: `Logical constraint "${r}" could not be evaluated: ${a.reason}.`
|
|
2046
|
+
});
|
|
2047
|
+
continue;
|
|
2048
|
+
}
|
|
2049
|
+
S++, a.value ? m(a.violation) : h({
|
|
2050
|
+
type: "logical_constraint",
|
|
2051
|
+
target: "logical_constraint",
|
|
2052
|
+
name: r,
|
|
2053
|
+
actual: !1,
|
|
2054
|
+
limit: !0,
|
|
2055
|
+
violation: 1,
|
|
2056
|
+
signedViolation: -1,
|
|
2057
|
+
message: `Logical constraint "${r}" evaluated to false.`
|
|
2058
|
+
});
|
|
2059
|
+
}
|
|
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;
|
|
2061
|
+
return {
|
|
2062
|
+
valid: E && s.length === 0,
|
|
2063
|
+
complete: E,
|
|
2064
|
+
violations: s,
|
|
2065
|
+
violationsByName: c,
|
|
2066
|
+
uncheckedConstraints: l,
|
|
2067
|
+
missingVariables: u,
|
|
2068
|
+
maxViolation: p,
|
|
2069
|
+
summary: {
|
|
2070
|
+
checkedVariables: v,
|
|
2071
|
+
totalVariables: e.variables.length,
|
|
2072
|
+
checkedBoolVariables: b,
|
|
2073
|
+
totalBoolVariables: e.boolVars.length,
|
|
2074
|
+
checkedLinearConstraints: x,
|
|
2075
|
+
totalLinearConstraints: e.constraints.length,
|
|
2076
|
+
checkedLogicalConstraints: S,
|
|
2077
|
+
totalLogicalConstraints: e.logicalConstraints.length
|
|
2078
|
+
}
|
|
2079
|
+
};
|
|
2080
|
+
}
|
|
2081
|
+
//#endregion
|
|
2082
|
+
//#region src/modeler/big-m.ts
|
|
2083
|
+
function ze(e, t) {
|
|
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}.`);
|
|
2085
|
+
}
|
|
2086
|
+
function Be(e, t, n) {
|
|
2087
|
+
let r = e.constant === void 0 ? 0 : e.constant;
|
|
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}).`);
|
|
2089
|
+
let i = t - r;
|
|
2090
|
+
if (!Number.isFinite(i)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": effective right-hand side (${t} - ${r}) overflows finite floating-point range. Please rescale coefficients/constants.`);
|
|
2091
|
+
for (let [t, r] of e.terms) {
|
|
2092
|
+
if (!Number.isFinite(r)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": variable "${t.name}" has non-finite coefficient (${r}).`);
|
|
2093
|
+
if (Number.isNaN(t.lb) || Number.isNaN(t.ub) || t.lb === Infinity || t.ub === -Infinity || t.lb > t.ub) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": variable "${t.name}" has invalid bounds [${t.lb}, ${t.ub}].`);
|
|
2094
|
+
}
|
|
2095
|
+
return i;
|
|
2096
|
+
}
|
|
2097
|
+
function q(e, t, n) {
|
|
2098
|
+
let r = Be(e, t, n), i = 0;
|
|
2099
|
+
for (let [t, r] of e.terms) {
|
|
2100
|
+
if (r === 0) continue;
|
|
2101
|
+
let e;
|
|
2102
|
+
if (r > 0) {
|
|
2103
|
+
if (!Number.isFinite(t.ub)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": variable "${t.name}" lacks a finite upper bound (required because coefficient ${r} is positive in <= constraint). Please set an explicit finite upper bound on the variable or specify { M } explicitly in indicator options.`);
|
|
2104
|
+
e = t.ub;
|
|
2105
|
+
} else {
|
|
2106
|
+
if (!Number.isFinite(t.lb)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": variable "${t.name}" lacks a finite lower bound (required because coefficient ${r} is negative in <= constraint). Please set an explicit finite lower bound on the variable or specify { M } explicitly in indicator options.`);
|
|
2107
|
+
e = t.lb;
|
|
2108
|
+
}
|
|
2109
|
+
let a = r * e;
|
|
2110
|
+
if (i += a, !Number.isFinite(a) || !Number.isFinite(i)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": numeric overflow while bounding contribution of variable "${t.name}". Please rescale coefficients/bounds or specify a finite { M } explicitly.`);
|
|
2111
|
+
}
|
|
2112
|
+
let a = i - r;
|
|
2113
|
+
if (!Number.isFinite(a)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": numeric overflow while computing Big-M (${i} - ${r}). Please rescale coefficients/bounds or specify a finite { M } explicitly.`);
|
|
2114
|
+
let o = Math.max(0, a);
|
|
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.`);
|
|
2116
|
+
return o;
|
|
2117
|
+
}
|
|
2118
|
+
function J(e, t, n) {
|
|
2119
|
+
let r = Be(e, t, n), i = 0;
|
|
2120
|
+
for (let [t, r] of e.terms) {
|
|
2121
|
+
if (r === 0) continue;
|
|
2122
|
+
let e;
|
|
2123
|
+
if (r > 0) {
|
|
2124
|
+
if (!Number.isFinite(t.lb)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": variable "${t.name}" lacks a finite lower bound (required because coefficient ${r} is positive in >= constraint). Please set an explicit finite lower bound on the variable or specify { M } explicitly in indicator options.`);
|
|
2125
|
+
e = t.lb;
|
|
2126
|
+
} else {
|
|
2127
|
+
if (!Number.isFinite(t.ub)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": variable "${t.name}" lacks a finite upper bound (required because coefficient ${r} is negative in >= constraint). Please set an explicit finite upper bound on the variable or specify { M } explicitly in indicator options.`);
|
|
2128
|
+
e = t.ub;
|
|
2129
|
+
}
|
|
2130
|
+
let a = r * e;
|
|
2131
|
+
if (i += a, !Number.isFinite(a) || !Number.isFinite(i)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": numeric overflow while bounding contribution of variable "${t.name}". Please rescale coefficients/bounds or specify a finite { M } explicitly.`);
|
|
2132
|
+
}
|
|
2133
|
+
let a = r - i;
|
|
2134
|
+
if (!Number.isFinite(a)) throw Error(`Cannot derive safe Big-M for indicator constraint "${n}": numeric overflow while computing Big-M (${r} - ${i}). Please rescale coefficients/bounds or specify a finite { M } explicitly.`);
|
|
2135
|
+
let o = Math.max(0, a);
|
|
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.`);
|
|
2137
|
+
return o;
|
|
2138
|
+
}
|
|
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}].`);
|
|
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.`);
|
|
2142
|
+
let s = Be(t, r, o);
|
|
2143
|
+
if (i !== 0 && i !== 1) throw Error(`Invalid activeValue: ${i}. Indicator activation value must be 0 or 1.`);
|
|
2144
|
+
if (n !== "<=" && n !== ">=") throw Error(`Invalid indicator sense for "${o}": expected "<=" or ">=", received "${String(n)}".`);
|
|
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}.`);
|
|
2146
|
+
let c = t.terms.get(e);
|
|
2147
|
+
if (c !== void 0 && c !== 0) throw Error(`Indicator constraint "${o}" cannot include its own binary activation variable "${e.name}" in the linear expression.`);
|
|
2148
|
+
let l, u;
|
|
2149
|
+
if (i === 1 ? n === "<=" ? (l = a, u = s + a) : (l = -a, u = s - a) : n === "<=" ? (l = -a, u = s) : (l = a, u = s), !Number.isFinite(u)) throw Error(`Cannot construct finite indicator constraint "${o}": shifted right-hand side overflows finite floating-point range. Please rescale coefficients/bounds or specify a smaller finite { M }.`);
|
|
2150
|
+
let d = /* @__PURE__ */ new Map();
|
|
2151
|
+
for (let [e, n] of t.terms) n !== 0 && d.set(e, n);
|
|
2152
|
+
return l !== 0 && d.set(e, l), {
|
|
2153
|
+
lhs: new C(d, 0),
|
|
2154
|
+
rhs: u
|
|
2155
|
+
};
|
|
2156
|
+
}
|
|
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
|
|
2679
|
+
//#region src/modeler/model.ts
|
|
2680
|
+
function Z(e) {
|
|
2681
|
+
return Array.isArray(e) || typeof e == "object" && !!e && !(e instanceof String) && typeof e[Symbol.iterator] == "function";
|
|
2682
|
+
}
|
|
2683
|
+
function Q(e) {
|
|
2684
|
+
return typeof e == "object" && !!e && !Array.isArray(e) && !(e instanceof String) && typeof e[Symbol.iterator] != "function";
|
|
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
|
+
}
|
|
2689
|
+
function $(e, t) {
|
|
2690
|
+
if (!Number.isInteger(e) || e < 0) throw Error(`Invalid count (${e}) for ${t} variable creation: count must be a non-negative integer.`);
|
|
2691
|
+
}
|
|
2692
|
+
var Ze = class {
|
|
2693
|
+
name;
|
|
2694
|
+
_sense;
|
|
2695
|
+
_objectiveExpr;
|
|
2696
|
+
variables = [];
|
|
2697
|
+
constraints = [];
|
|
2698
|
+
boolVars = [];
|
|
1052
2699
|
logicalConstraints = [];
|
|
1053
|
-
unsatCore =
|
|
2700
|
+
unsatCore = void 0;
|
|
2701
|
+
_conflicts = void 0;
|
|
1054
2702
|
values = /* @__PURE__ */ new Map();
|
|
1055
2703
|
varMapByName = /* @__PURE__ */ new Map();
|
|
2704
|
+
varPrefixCounters = /* @__PURE__ */ new Map();
|
|
1056
2705
|
boolVarMapByName = /* @__PURE__ */ new Map();
|
|
1057
2706
|
boolVarPrefixCounters = /* @__PURE__ */ new Map();
|
|
1058
2707
|
constrMapByName = /* @__PURE__ */ new Map();
|
|
2708
|
+
constrPrefixCounters = /* @__PURE__ */ new Map();
|
|
2709
|
+
logicalConstrMapByName = /* @__PURE__ */ new Map();
|
|
2710
|
+
logicalConstrCounter = 0;
|
|
1059
2711
|
status = "NotSolved";
|
|
2712
|
+
terminationStatus = "NotSolved";
|
|
2713
|
+
hasPrimalSolution = !1;
|
|
1060
2714
|
objectiveValue = null;
|
|
2715
|
+
objectiveBound = void 0;
|
|
2716
|
+
relGap = void 0;
|
|
2717
|
+
mipGap = void 0;
|
|
2718
|
+
absGap = void 0;
|
|
1061
2719
|
runTime = 0;
|
|
1062
2720
|
solution = null;
|
|
1063
2721
|
solver = null;
|
|
2722
|
+
decomposition;
|
|
2723
|
+
_linkingConstraints;
|
|
2724
|
+
hasSolutionState = !1;
|
|
2725
|
+
modelRevision = 0;
|
|
2726
|
+
activeOperationId = 0;
|
|
2727
|
+
batchDepth = 0;
|
|
2728
|
+
batchMutated = !1;
|
|
2729
|
+
batchUndoActions = [];
|
|
1064
2730
|
constructor(e = {}, t) {
|
|
1065
2731
|
let n;
|
|
1066
2732
|
n = typeof e == "string" ? {
|
|
1067
2733
|
...t,
|
|
1068
2734
|
name: e
|
|
1069
|
-
} : e, this.name = n.name || "OptimizationModel", this.
|
|
2735
|
+
} : e, this.name = n.name || "OptimizationModel", this._sense = s(n.sense), this._objectiveExpr = new C(), n.solver && (this.solver = V(n.solver));
|
|
2736
|
+
}
|
|
2737
|
+
get sense() {
|
|
2738
|
+
return this._sense;
|
|
2739
|
+
}
|
|
2740
|
+
set sense(e) {
|
|
2741
|
+
let t = s(e);
|
|
2742
|
+
this._sense !== t && (this._sense = t, this.recordModelMutation());
|
|
2743
|
+
}
|
|
2744
|
+
get objectiveExpr() {
|
|
2745
|
+
return this._objectiveExpr.clone();
|
|
2746
|
+
}
|
|
2747
|
+
set objectiveExpr(e) {
|
|
2748
|
+
this.applyObjective(e);
|
|
1070
2749
|
}
|
|
1071
|
-
get
|
|
1072
|
-
return this.
|
|
2750
|
+
get conflicts() {
|
|
2751
|
+
return this._conflicts ?? this.unsatCore;
|
|
1073
2752
|
}
|
|
1074
|
-
|
|
1075
|
-
|
|
2753
|
+
set conflicts(e) {
|
|
2754
|
+
this._conflicts = e;
|
|
1076
2755
|
}
|
|
1077
2756
|
get numVars() {
|
|
1078
2757
|
return this.variables.length;
|
|
@@ -1080,50 +2759,123 @@ var se = class {
|
|
|
1080
2759
|
get numConstrs() {
|
|
1081
2760
|
return this.constraints.length;
|
|
1082
2761
|
}
|
|
1083
|
-
|
|
1084
|
-
if (
|
|
1085
|
-
|
|
1086
|
-
for (let
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
2762
|
+
clearSolutionFields() {
|
|
2763
|
+
if (this.hasSolutionState || this.status !== "NotSolved" || this.terminationStatus !== "NotSolved" || this.hasPrimalSolution || this.solution !== null || this.unsatCore !== void 0) {
|
|
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();
|
|
2765
|
+
for (let e of this.variables) e.value = null, e.reducedCost = null;
|
|
2766
|
+
for (let e of this.boolVars) e.value = null;
|
|
2767
|
+
for (let e of this.constraints) e.dual = null, e.slack = null;
|
|
2768
|
+
}
|
|
2769
|
+
}
|
|
2770
|
+
recordModelMutation() {
|
|
2771
|
+
if (this.batchDepth > 0) {
|
|
2772
|
+
this.batchMutated = !0;
|
|
2773
|
+
return;
|
|
2774
|
+
}
|
|
2775
|
+
this.modelRevision++, this.clearSolutionFields();
|
|
2776
|
+
}
|
|
2777
|
+
notifyMutation() {
|
|
2778
|
+
this.recordModelMutation();
|
|
2779
|
+
}
|
|
2780
|
+
resetSolutionState() {
|
|
2781
|
+
this.recordModelMutation();
|
|
2782
|
+
}
|
|
2783
|
+
runTransactionalBatch(e) {
|
|
2784
|
+
if (this.batchDepth > 0) return e();
|
|
2785
|
+
let t = this.variables.length, n = this.boolVars.length, r = this.constraints.length, i = this.logicalConstraints.length, a = new Map(this.varPrefixCounters), o = new Map(this.boolVarPrefixCounters), s = new Map(this.constrPrefixCounters), c = this.logicalConstrCounter;
|
|
2786
|
+
this.batchDepth = 1, this.batchMutated = !1, this.batchUndoActions = [];
|
|
2787
|
+
try {
|
|
2788
|
+
let t = e();
|
|
2789
|
+
this.batchDepth = 0;
|
|
2790
|
+
let n = this.batchMutated;
|
|
2791
|
+
return this.batchMutated = !1, this.batchUndoActions = [], n && this.recordModelMutation(), t;
|
|
2792
|
+
} catch (e) {
|
|
2793
|
+
this.batchDepth = 0, this.batchMutated = !1;
|
|
2794
|
+
for (let e = t; e < this.variables.length; e++) {
|
|
2795
|
+
let t = this.variables[e];
|
|
2796
|
+
this.varMapByName.delete(t.name), t.ownerModel = null, ne(t, this);
|
|
2797
|
+
}
|
|
2798
|
+
this.variables.length = t;
|
|
2799
|
+
for (let e = n; e < this.boolVars.length; e++) {
|
|
2800
|
+
let t = this.boolVars[e];
|
|
2801
|
+
this.boolVarMapByName.delete(t.name);
|
|
1093
2802
|
}
|
|
1094
|
-
|
|
2803
|
+
this.boolVars.length = n;
|
|
2804
|
+
for (let e = r; e < this.constraints.length; e++) {
|
|
2805
|
+
let t = this.constraints[e];
|
|
2806
|
+
this.constrMapByName.delete(t.name);
|
|
2807
|
+
}
|
|
2808
|
+
this.constraints.length = r;
|
|
2809
|
+
for (let e = i; e < this.logicalConstraints.length; e++) {
|
|
2810
|
+
let t = this.logicalConstraints[e];
|
|
2811
|
+
this.logicalConstrMapByName.delete(t.name);
|
|
2812
|
+
}
|
|
2813
|
+
this.logicalConstraints.length = i;
|
|
2814
|
+
for (let e = this.batchUndoActions.length - 1; e >= 0; e--) this.batchUndoActions[e]();
|
|
2815
|
+
throw this.batchUndoActions = [], this.varPrefixCounters = a, this.boolVarPrefixCounters = o, this.constrPrefixCounters = s, this.logicalConstrCounter = c, e;
|
|
1095
2816
|
}
|
|
1096
|
-
|
|
1097
|
-
|
|
2817
|
+
}
|
|
2818
|
+
createDomainVars(e, t, n, r) {
|
|
2819
|
+
let i = e.toLowerCase(), a = typeof t == "number", o = typeof n == "number", s = Z(t), c = Z(n);
|
|
2820
|
+
if (o || c) {
|
|
2821
|
+
if (a && $(t, i), o && $(n, i), !a && !s || r !== void 0 && !Q(r)) throw Error(`Invalid arguments provided for ${i} variable creation`);
|
|
2822
|
+
let c = a ? Array.from({ length: t }, (e, t) => t) : Array.from(t), l = o ? Array.from({ length: n }, (e, t) => t) : n === t ? c : Array.from(n), u = r || {}, d = u.prefix || u.name || "x";
|
|
2823
|
+
return this.runTransactionalBatch(() => {
|
|
2824
|
+
let t = a ? [] : {};
|
|
2825
|
+
for (let n of c) {
|
|
2826
|
+
let r = o ? [] : {};
|
|
2827
|
+
for (let t of l) r[t] = this.addVar({
|
|
2828
|
+
...u,
|
|
2829
|
+
type: e,
|
|
2830
|
+
name: `${d}_${n}_${t}`
|
|
2831
|
+
});
|
|
2832
|
+
t[n] = r;
|
|
2833
|
+
}
|
|
2834
|
+
return t;
|
|
2835
|
+
});
|
|
2836
|
+
}
|
|
2837
|
+
if (typeof t == "string" || t === void 0) {
|
|
2838
|
+
if (n !== void 0 && !Q(n)) throw Error(`Invalid arguments provided for ${i} variable creation`);
|
|
2839
|
+
let r = n || {}, a = typeof t == "string" ? t : r.name;
|
|
1098
2840
|
return this.addVar({
|
|
1099
2841
|
...r,
|
|
1100
2842
|
type: e,
|
|
1101
|
-
name:
|
|
2843
|
+
name: a
|
|
1102
2844
|
});
|
|
1103
2845
|
}
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
let
|
|
1107
|
-
|
|
1108
|
-
...
|
|
2846
|
+
if (Q(t)) {
|
|
2847
|
+
if (n !== void 0) throw Error(`Invalid arguments provided for ${i} variable creation`);
|
|
2848
|
+
let r = t;
|
|
2849
|
+
return this.addVar({
|
|
2850
|
+
...r,
|
|
2851
|
+
type: e
|
|
2852
|
+
});
|
|
2853
|
+
}
|
|
2854
|
+
if (n !== void 0 && !Q(n)) throw Error(`Invalid arguments provided for ${i} variable creation`);
|
|
2855
|
+
let l = n || {}, u = l.prefix || l.name;
|
|
2856
|
+
if (typeof t == "number") return $(t, i), this.runTransactionalBatch(() => {
|
|
2857
|
+
let n = [], r = u || "x";
|
|
2858
|
+
for (let i = 0; i < t; i++) n.push(this.addVar({
|
|
2859
|
+
...l,
|
|
1109
2860
|
type: e,
|
|
1110
|
-
name:
|
|
2861
|
+
name: void 0,
|
|
2862
|
+
prefix: r
|
|
1111
2863
|
}));
|
|
1112
2864
|
return n;
|
|
1113
|
-
}
|
|
1114
|
-
if (
|
|
2865
|
+
});
|
|
2866
|
+
if (Z(t)) return this.runTransactionalBatch(() => {
|
|
1115
2867
|
let n = {};
|
|
1116
2868
|
for (let r of t) {
|
|
1117
|
-
let t =
|
|
2869
|
+
let t = u ? `${u}_${r}` : `${r}`;
|
|
1118
2870
|
n[r] = this.addVar({
|
|
1119
|
-
...
|
|
2871
|
+
...l,
|
|
1120
2872
|
type: e,
|
|
1121
2873
|
name: t
|
|
1122
2874
|
});
|
|
1123
2875
|
}
|
|
1124
2876
|
return n;
|
|
1125
|
-
}
|
|
1126
|
-
throw Error(`Invalid arguments provided for ${
|
|
2877
|
+
});
|
|
2878
|
+
throw Error(`Invalid arguments provided for ${i} variable creation`);
|
|
1127
2879
|
}
|
|
1128
2880
|
binary(e, t, n) {
|
|
1129
2881
|
return this.createDomainVars("Binary", e, t, n);
|
|
@@ -1134,53 +2886,128 @@ var se = class {
|
|
|
1134
2886
|
continuous(e, t, n) {
|
|
1135
2887
|
return this.createDomainVars("Continuous", e, t, n);
|
|
1136
2888
|
}
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
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);
|
|
1143
2916
|
}
|
|
1144
|
-
return s;
|
|
1145
2917
|
}
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
2918
|
+
return n;
|
|
2919
|
+
}
|
|
2920
|
+
bool(e, t, n) {
|
|
2921
|
+
let r = typeof e == "number", i = typeof t == "number", a = Z(e), o = Z(t);
|
|
2922
|
+
if (i || o) {
|
|
2923
|
+
if (r && $(e, "boolean"), i && $(t, "boolean"), !r && !a || n !== void 0 && !Q(n)) throw Error("Invalid arguments provided for boolean variable creation");
|
|
2924
|
+
let o = r ? Array.from({ length: e }, (e, t) => t) : Array.from(e), s = i ? Array.from({ length: t }, (e, t) => t) : t === e ? o : Array.from(t), c = n || {}, l = c.prefix || c.name || "p";
|
|
2925
|
+
return this.runTransactionalBatch(() => {
|
|
2926
|
+
let e = r ? [] : {};
|
|
2927
|
+
for (let t of o) {
|
|
2928
|
+
let n = i ? [] : {};
|
|
2929
|
+
for (let e of s) n[e] = this.createBoolVar(`${l}_${t}_${e}`);
|
|
2930
|
+
e[t] = n;
|
|
2931
|
+
}
|
|
2932
|
+
return e;
|
|
2933
|
+
});
|
|
2934
|
+
}
|
|
2935
|
+
if (typeof e == "string" || e === void 0) {
|
|
2936
|
+
if (t !== void 0 && !Q(t)) throw Error("Invalid arguments provided for boolean variable creation");
|
|
2937
|
+
let n = t || {}, r = typeof e == "string" ? e : n.name;
|
|
2938
|
+
return this.createBoolVar(r, n.prefix);
|
|
1152
2939
|
}
|
|
1153
|
-
if (
|
|
2940
|
+
if (Q(e)) {
|
|
2941
|
+
if (t !== void 0) throw Error("Invalid arguments provided for boolean variable creation");
|
|
2942
|
+
let n = e;
|
|
2943
|
+
return this.createBoolVar(n.name, n.prefix);
|
|
2944
|
+
}
|
|
2945
|
+
if (t !== void 0 && !Q(t)) throw Error("Invalid arguments provided for boolean variable creation");
|
|
2946
|
+
let s = t || {}, c = s.prefix || s.name;
|
|
2947
|
+
if (typeof e == "number") return $(e, "boolean"), this.runTransactionalBatch(() => {
|
|
2948
|
+
let t = [], n = c || "p";
|
|
2949
|
+
for (let r = 0; r < e; r++) t.push(this.createBoolVar(void 0, n));
|
|
2950
|
+
return t;
|
|
2951
|
+
});
|
|
2952
|
+
if (Z(e)) return this.runTransactionalBatch(() => {
|
|
1154
2953
|
let t = {};
|
|
1155
2954
|
for (let n of e) {
|
|
1156
|
-
let e =
|
|
2955
|
+
let e = c ? `${c}_${n}` : `${n}`;
|
|
1157
2956
|
t[n] = this.createBoolVar(e);
|
|
1158
2957
|
}
|
|
1159
2958
|
return t;
|
|
1160
|
-
}
|
|
2959
|
+
});
|
|
1161
2960
|
throw Error("Invalid arguments provided for boolean variable creation");
|
|
1162
2961
|
}
|
|
1163
2962
|
hasVarName(e) {
|
|
1164
2963
|
return this.varMapByName.has(e) || this.boolVarMapByName.has(e);
|
|
1165
2964
|
}
|
|
2965
|
+
getNextVarName(e) {
|
|
2966
|
+
let t = this.varPrefixCounters.get(e) ?? 0, n = `${e}_${t}`;
|
|
2967
|
+
for (; this.hasVarName(n);) t++, n = `${e}_${t}`;
|
|
2968
|
+
return this.varPrefixCounters.set(e, t + 1), n;
|
|
2969
|
+
}
|
|
1166
2970
|
getNextBoolVarName(e) {
|
|
1167
2971
|
let t = this.boolVarPrefixCounters.get(e) ?? 0, n = `${e}_${t}`;
|
|
1168
|
-
for (; this.hasVarName(n);) t++, n = `${e}_${t}`;
|
|
2972
|
+
for (; this.hasVarName(n) || this.hasConstraintName(n);) t++, n = `${e}_${t}`;
|
|
1169
2973
|
return this.boolVarPrefixCounters.set(e, t + 1), n;
|
|
1170
2974
|
}
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
return this.
|
|
2975
|
+
hasConstraintName(e) {
|
|
2976
|
+
return this.constrMapByName.has(e) || this.logicalConstrMapByName.has(e);
|
|
2977
|
+
}
|
|
2978
|
+
hasBoolVarName(e) {
|
|
2979
|
+
return this.boolVarMapByName.has(e);
|
|
2980
|
+
}
|
|
2981
|
+
getNextConstrName(e = "c") {
|
|
2982
|
+
let t = this.constrPrefixCounters.get(e) ?? 1, n = `${e}_${t}`;
|
|
2983
|
+
for (; this.hasConstraintName(n) || this.hasBoolVarName(n);) t++, n = `${e}_${t}`;
|
|
2984
|
+
return this.constrPrefixCounters.set(e, t + 1), n;
|
|
2985
|
+
}
|
|
2986
|
+
getNextLogicalConstrName() {
|
|
2987
|
+
let e = this.logicalConstrCounter + 1, t = `lc_${e}`;
|
|
2988
|
+
for (; this.hasConstraintName(t) || this.hasBoolVarName(t);) e++, t = `lc_${e}`;
|
|
2989
|
+
return this.logicalConstrCounter = e, t;
|
|
2990
|
+
}
|
|
2991
|
+
createBoolVar(e, t) {
|
|
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);
|
|
2993
|
+
if (this.hasVarName(a)) throw Error(`Variable with name '${a}' already exists in model`);
|
|
2994
|
+
if (this.hasConstraintName(a)) throw Error(`Boolean variable name '${a}' conflicts with an existing constraint in model`);
|
|
2995
|
+
let o = new d(a);
|
|
2996
|
+
return this.boolVars.push(o), this.boolVarMapByName.set(o.name, o), this.recordModelMutation(), o;
|
|
1176
2997
|
}
|
|
1177
2998
|
addVar(e) {
|
|
1178
|
-
let t = e || {}, n = typeof t.name == "string" ? t.name.trim() : void 0, r = n && n.length > 0 ? n : void 0, i =
|
|
1179
|
-
|
|
1180
|
-
name
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
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);
|
|
3000
|
+
try {
|
|
3001
|
+
if (this.hasVarName(s)) throw Error(`Variable with name '${s}' already exists in model`);
|
|
3002
|
+
let e = new M({
|
|
3003
|
+
...t,
|
|
3004
|
+
name: s,
|
|
3005
|
+
prefix: a
|
|
3006
|
+
});
|
|
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;
|
|
3008
|
+
} catch (e) {
|
|
3009
|
+
throw r === void 0 && (o === void 0 ? this.varPrefixCounters.delete(a) : this.varPrefixCounters.set(a, o)), e;
|
|
3010
|
+
}
|
|
1184
3011
|
}
|
|
1185
3012
|
getVarByName(e) {
|
|
1186
3013
|
return this.varMapByName.get(e);
|
|
@@ -1191,28 +3018,46 @@ var se = class {
|
|
|
1191
3018
|
getConstraintByName(e) {
|
|
1192
3019
|
return this.constrMapByName.get(e);
|
|
1193
3020
|
}
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
this.
|
|
1203
|
-
}
|
|
1204
|
-
|
|
1205
|
-
if (
|
|
1206
|
-
|
|
3021
|
+
getLogicalConstraintByName(e) {
|
|
3022
|
+
return this.logicalConstrMapByName.get(e);
|
|
3023
|
+
}
|
|
3024
|
+
objective(e) {
|
|
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;
|
|
3030
|
+
}
|
|
3031
|
+
applyObjective(e, t) {
|
|
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);
|
|
3036
|
+
else if (e instanceof S) r = e.clone();
|
|
3037
|
+
else if (e instanceof C) r = e.clone();
|
|
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") {
|
|
3039
|
+
let t = e;
|
|
3040
|
+
r = new S(t.linearTerms, t.quadTerms, t.constant);
|
|
3041
|
+
} else if (typeof e == "object" && e && "terms" in e && e.terms instanceof Map && typeof e.constant == "number") {
|
|
3042
|
+
let t = e;
|
|
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);
|
|
3045
|
+
else throw Error("Invalid objective expression: expected a finite number, Var, LinExpr, QuadExpr, or arithmetic expression string.");
|
|
3046
|
+
oe(r, this.name, (e) => this.varMapByName.get(e.name) === e), this._sense = n, this._objectiveExpr = r, this.recordModelMutation();
|
|
3047
|
+
}
|
|
3048
|
+
constraint(e, t) {
|
|
3049
|
+
if (Array.isArray(e)) return this.runTransactionalBatch(() => {
|
|
3050
|
+
for (let t of e) this.constraint(t);
|
|
1207
3051
|
return this;
|
|
1208
|
-
}
|
|
1209
|
-
if (e instanceof S) throw Error("
|
|
1210
|
-
if (e instanceof C) throw Error("
|
|
3052
|
+
});
|
|
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().`);
|
|
1211
3056
|
return this.addConstraint(e, t), this;
|
|
1212
3057
|
}
|
|
1213
3058
|
getValues(e) {
|
|
1214
3059
|
if (e == null) return null;
|
|
1215
|
-
if (e instanceof
|
|
3060
|
+
if (e instanceof M || e instanceof d) return e.value;
|
|
1216
3061
|
if (Array.isArray(e)) return e.map((e) => this.getValues(e));
|
|
1217
3062
|
if (typeof e == "object") {
|
|
1218
3063
|
let t = {};
|
|
@@ -1222,157 +3067,417 @@ var se = class {
|
|
|
1222
3067
|
return null;
|
|
1223
3068
|
}
|
|
1224
3069
|
addConstraint(e, t) {
|
|
1225
|
-
if (e instanceof S) throw Error("
|
|
1226
|
-
if (e instanceof C) throw Error("
|
|
1227
|
-
if (e
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
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) {
|
|
3074
|
+
let n = typeof t == "string" && t.trim().length > 0 ? t.trim() : void 0;
|
|
3075
|
+
if (n !== void 0) {
|
|
3076
|
+
if (this.hasConstraintName(n)) throw Error(`Constraint with name '${n}' already exists in model`);
|
|
3077
|
+
if (this.hasBoolVarName(n)) throw Error(`Constraint name '${n}' conflicts with an existing Boolean variable in model`);
|
|
3078
|
+
}
|
|
3079
|
+
let r = this.logicalConstrCounter, i = n ?? this.getNextLogicalConstrName();
|
|
3080
|
+
try {
|
|
3081
|
+
se(e, i, this.name, (e) => this.varMapByName.get(e.name) === e, (e) => this.boolVarMapByName.get(e.name) === e, this);
|
|
3082
|
+
} catch (e) {
|
|
3083
|
+
throw n === void 0 && (this.logicalConstrCounter = r), e;
|
|
3084
|
+
}
|
|
3085
|
+
k(e, this, this.batchDepth > 0 ? this.batchUndoActions : void 0);
|
|
3086
|
+
let a = {
|
|
3087
|
+
name: i,
|
|
1231
3088
|
expr: e
|
|
1232
|
-
}
|
|
3089
|
+
};
|
|
3090
|
+
return this.logicalConstraints.push(a), this.logicalConstrMapByName.set(i, a), this.recordModelMutation(), e;
|
|
1233
3091
|
}
|
|
1234
|
-
let n;
|
|
1235
|
-
if (typeof
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
return this;
|
|
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));
|
|
3095
|
+
let r = typeof t == "string" && t.trim().length > 0 ? t.trim() : n.hasExplicitName ? n.name.trim() : void 0;
|
|
3096
|
+
if (r !== void 0) {
|
|
3097
|
+
if (this.hasConstraintName(r)) throw Error(`Constraint with name '${r}' already exists in model`);
|
|
3098
|
+
if (this.hasBoolVarName(r)) throw Error(`Constraint name '${r}' conflicts with an existing Boolean variable in model`);
|
|
1242
3099
|
}
|
|
1243
|
-
|
|
3100
|
+
let i = this.constrPrefixCounters.get("c"), a = r ?? this.getNextConstrName("c"), o;
|
|
3101
|
+
try {
|
|
3102
|
+
j(n, this.name, (e) => this.varMapByName.get(e.name) === e, a), o = te(n, this);
|
|
3103
|
+
} catch (e) {
|
|
3104
|
+
throw r === void 0 && (i === void 0 ? this.constrPrefixCounters.delete("c") : this.constrPrefixCounters.set("c", i)), e;
|
|
3105
|
+
}
|
|
3106
|
+
let s = n.name, c = n.hasExplicitName, l = n.ownerModel, d = o;
|
|
3107
|
+
return this.batchUndoActions.push(() => {
|
|
3108
|
+
n.ownerModel = l, n._assignModelName(s, c), re(n, this, d);
|
|
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;
|
|
1244
3110
|
}
|
|
1245
3111
|
indicator(e, t, n = {}) {
|
|
1246
|
-
if (
|
|
1247
|
-
if (!(
|
|
1248
|
-
|
|
1249
|
-
if (
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
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.");
|
|
3117
|
+
let r = t, i = n.activeValue === void 0 ? 1 : n.activeValue;
|
|
3118
|
+
if (i !== 0 && i !== 1) throw Error(`Invalid activeValue: ${i}. Indicator activeValue must be 0 or 1.`);
|
|
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.`);
|
|
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;
|
|
3123
|
+
else do {
|
|
3124
|
+
let t = this.getNextConstrName("c");
|
|
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 = [];
|
|
3128
|
+
try {
|
|
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);
|
|
3132
|
+
let t = (e) => this.varMapByName.get(e.name) === e;
|
|
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.`);
|
|
3134
|
+
if (c === "<=" || c === "==") {
|
|
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]);
|
|
1262
3137
|
}
|
|
1263
|
-
if (
|
|
1264
|
-
let t =
|
|
1265
|
-
|
|
3138
|
+
if (c === ">=" || c === "==") {
|
|
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]);
|
|
1266
3141
|
}
|
|
3142
|
+
for (let [e, n] of m) j(e, this.name, t, n);
|
|
3143
|
+
} catch (e) {
|
|
3144
|
+
throw o === void 0 ? this.constrPrefixCounters.delete("c") : this.constrPrefixCounters.set("c", o), e;
|
|
1267
3145
|
}
|
|
1268
|
-
return
|
|
3146
|
+
return this.runTransactionalBatch(() => m.map(([e, t]) => this.addConstraint(e, t)));
|
|
1269
3147
|
}
|
|
1270
3148
|
toLpString() {
|
|
1271
|
-
|
|
3149
|
+
this.validateIntegrity();
|
|
3150
|
+
let { lpString: e } = L({
|
|
1272
3151
|
name: this.name,
|
|
1273
3152
|
sense: this.sense,
|
|
1274
|
-
objective: this.
|
|
3153
|
+
objective: this.objectiveExpr,
|
|
1275
3154
|
constraints: this.constraints,
|
|
1276
3155
|
variables: this.variables
|
|
1277
3156
|
});
|
|
1278
3157
|
return e;
|
|
1279
3158
|
}
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
3159
|
+
validateIntegrity() {
|
|
3160
|
+
ce(this);
|
|
3161
|
+
}
|
|
3162
|
+
ensureExecutionValid(e, t, n) {
|
|
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.`);
|
|
3164
|
+
if (this.activeOperationId !== t) throw Error(`Stale ${n}() result discarded because a newer solve or check operation was started on model "${this.name}".`);
|
|
3165
|
+
}
|
|
3166
|
+
wrapSolveOptions(e, t, n) {
|
|
3167
|
+
let r = e.onProgress;
|
|
3168
|
+
return r ? {
|
|
3169
|
+
...e,
|
|
3170
|
+
onProgress: (e) => {
|
|
3171
|
+
this.activeOperationId === n && this.modelRevision === t && r(e);
|
|
3172
|
+
}
|
|
3173
|
+
} : e;
|
|
3174
|
+
}
|
|
3175
|
+
hasPrimalFromResult(e) {
|
|
3176
|
+
if (typeof e.hasPrimalSolution == "boolean") return e.hasPrimalSolution;
|
|
3177
|
+
let t = e.status, n = e.terminationStatus ?? t, r = e.values || {}, i = e.boolValues || {};
|
|
3178
|
+
return t !== "Infeasible" && t !== "Unsat" && t !== "Unbounded" && t !== "Error" && t !== "NotSolved" && n !== "Infeasible" && n !== "Unsat" && n !== "Unbounded" && n !== "InfeasibleOrUnbounded" && n !== "Error" && n !== "NotSolved" && (t === "Optimal" || t === "Feasible" || t === "Sat" || n === "Optimal" || n === "Feasible" || n === "Sat" || typeof e.objectiveValue == "number" && Number.isFinite(e.objectiveValue) || Object.values(r).some((e) => typeof e == "number" && Number.isFinite(e) || typeof e == "boolean") || Object.values(i).some((e) => typeof e == "boolean"));
|
|
3179
|
+
}
|
|
3180
|
+
resolveSolverAndOptions(e, t) {
|
|
3181
|
+
if (e && typeof e == "object" && "solve" in e && typeof e.solve == "function") {
|
|
3182
|
+
let { solver: n, ...r } = t || {};
|
|
3183
|
+
return {
|
|
3184
|
+
activeSolver: e,
|
|
3185
|
+
activeOptions: r
|
|
3186
|
+
};
|
|
3187
|
+
}
|
|
3188
|
+
if (typeof e == "function") {
|
|
3189
|
+
let { solver: n, ...r } = t || {};
|
|
3190
|
+
return {
|
|
3191
|
+
activeSolver: new e(r),
|
|
3192
|
+
activeOptions: r
|
|
3193
|
+
};
|
|
3194
|
+
}
|
|
3195
|
+
if (typeof e == "string") {
|
|
3196
|
+
let { solver: n, ...r } = t || {};
|
|
3197
|
+
return {
|
|
3198
|
+
activeSolver: V(e, r),
|
|
3199
|
+
activeOptions: r
|
|
3200
|
+
};
|
|
3201
|
+
}
|
|
3202
|
+
let { solver: n, ...r } = e || {};
|
|
3203
|
+
return n ? {
|
|
3204
|
+
activeSolver: V(n, r),
|
|
3205
|
+
activeOptions: r
|
|
3206
|
+
} : {
|
|
3207
|
+
activeSolver: this.solver || V(),
|
|
3208
|
+
activeOptions: r
|
|
3209
|
+
};
|
|
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
|
+
}
|
|
3221
|
+
async solve(e, t) {
|
|
3222
|
+
let n = ++this.activeOperationId, r = this.modelRevision;
|
|
3223
|
+
this.clearSolutionFields(), this.validateIntegrity();
|
|
3224
|
+
let { activeSolver: i, activeOptions: a } = this.resolveSolverAndOptions(e, t);
|
|
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 = {
|
|
1285
3228
|
name: this.name,
|
|
1286
3229
|
sense: this.sense,
|
|
1287
|
-
objective: this.
|
|
3230
|
+
objective: this._objectiveExpr,
|
|
3231
|
+
constraints: s.constraints,
|
|
3232
|
+
variables: s.variables,
|
|
3233
|
+
logicalConstraints: [],
|
|
3234
|
+
boolVars: []
|
|
3235
|
+
}) : o = {
|
|
3236
|
+
name: this.name,
|
|
3237
|
+
sense: this.sense,
|
|
3238
|
+
objective: this._objectiveExpr,
|
|
1288
3239
|
constraints: this.constraints,
|
|
1289
3240
|
variables: this.variables,
|
|
1290
3241
|
logicalConstraints: this.logicalConstraints,
|
|
1291
3242
|
boolVars: this.boolVars
|
|
1292
|
-
},
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
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;
|
|
3245
|
+
try {
|
|
3246
|
+
l = await i.solve(o, c);
|
|
3247
|
+
} catch (e) {
|
|
3248
|
+
throw this.activeOperationId === n && this.clearSolutionFields(), e;
|
|
3249
|
+
}
|
|
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) => {
|
|
3256
|
+
Object.defineProperty(e, t, {
|
|
3257
|
+
value: n,
|
|
3258
|
+
enumerable: !0,
|
|
3259
|
+
writable: !0,
|
|
3260
|
+
configurable: !0
|
|
3261
|
+
});
|
|
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)) {
|
|
3265
|
+
let n = this.getVarByName(e), r = this.getBoolVarByName(e);
|
|
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);
|
|
3267
|
+
} else if (typeof t == "boolean") {
|
|
3268
|
+
let n = t, r = this.getBoolVarByName(e);
|
|
3269
|
+
r ? (r.value = n, f(p, r.name, +!!n), this.values.set(r.name, n)) : this.values.set(e, n);
|
|
1308
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
|
+
}
|
|
3280
|
+
}
|
|
3281
|
+
}
|
|
3282
|
+
if (u && l.boolValues) for (let [e, t] of Object.entries(l.boolValues)) {
|
|
3283
|
+
if (typeof t != "boolean") continue;
|
|
3284
|
+
let n = this.getBoolVarByName(e);
|
|
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);
|
|
1309
3286
|
}
|
|
1310
|
-
if (
|
|
1311
|
-
|
|
1312
|
-
|
|
3287
|
+
if (u && l.reducedCosts) for (let [e, t] of Object.entries(l.reducedCosts)) {
|
|
3288
|
+
if (typeof t != "number" || !Number.isFinite(t)) continue;
|
|
3289
|
+
let n = this.getVarByName(e);
|
|
3290
|
+
n && (n.reducedCost = t, f(h, n.name, t));
|
|
1313
3291
|
}
|
|
1314
|
-
if (
|
|
1315
|
-
|
|
1316
|
-
|
|
3292
|
+
if (l.duals) for (let [e, t] of Object.entries(l.duals)) {
|
|
3293
|
+
if (typeof t != "number" || !Number.isFinite(t)) continue;
|
|
3294
|
+
let n = this.getConstraintByName(e);
|
|
3295
|
+
n && (n.dual = t, f(m, n.name, t));
|
|
1317
3296
|
}
|
|
1318
|
-
if (
|
|
1319
|
-
|
|
1320
|
-
|
|
3297
|
+
if (l.slacks) for (let [e, t] of Object.entries(l.slacks)) {
|
|
3298
|
+
if (typeof t != "number" || !Number.isFinite(t)) continue;
|
|
3299
|
+
let n = this.getConstraintByName(e);
|
|
3300
|
+
n && (n.slack = t, f(g, n.name, t));
|
|
1321
3301
|
}
|
|
1322
3302
|
return this.solution = {
|
|
1323
3303
|
status: this.status,
|
|
3304
|
+
terminationStatus: this.terminationStatus,
|
|
3305
|
+
hasPrimalSolution: this.hasPrimalSolution,
|
|
1324
3306
|
objectiveValue: this.objectiveValue,
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
3307
|
+
...this.objectiveBound === void 0 ? {} : { objectiveBound: this.objectiveBound },
|
|
3308
|
+
...this.relGap === void 0 ? {} : {
|
|
3309
|
+
relGap: this.relGap,
|
|
3310
|
+
mipGap: this.mipGap
|
|
3311
|
+
},
|
|
3312
|
+
...this.absGap === void 0 ? {} : { absGap: this.absGap },
|
|
3313
|
+
values: p,
|
|
3314
|
+
duals: m,
|
|
3315
|
+
reducedCosts: h,
|
|
3316
|
+
slacks: g,
|
|
1329
3317
|
runTime: this.runTime,
|
|
1330
|
-
raw:
|
|
1331
|
-
}, this.status;
|
|
1332
|
-
}
|
|
1333
|
-
async solve(e, t) {
|
|
1334
|
-
return this.optimize(e, t);
|
|
3318
|
+
raw: l.raw
|
|
3319
|
+
}, this.hasSolutionState = !0, this.status;
|
|
1335
3320
|
}
|
|
1336
3321
|
async check(e, t) {
|
|
1337
|
-
let n, r;
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
3322
|
+
let n = ++this.activeOperationId, r = this.modelRevision;
|
|
3323
|
+
this.clearSolutionFields(), this.validateIntegrity();
|
|
3324
|
+
let { activeSolver: i, activeOptions: a } = this.resolveSolverAndOptions(e, t);
|
|
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.`);
|
|
3326
|
+
let o = this.wrapSolveOptions(a, r, n), s = (e, t, n) => {
|
|
3327
|
+
Object.defineProperty(e, t, {
|
|
3328
|
+
value: n,
|
|
3329
|
+
enumerable: !0,
|
|
3330
|
+
writable: !0,
|
|
3331
|
+
configurable: !0
|
|
3332
|
+
});
|
|
3333
|
+
}, c = {
|
|
3334
|
+
name: this.name,
|
|
3335
|
+
variables: this.variables,
|
|
3336
|
+
boolVars: this.boolVars,
|
|
3337
|
+
constraints: this.constraints,
|
|
3338
|
+
logicalConstraints: this.logicalConstraints
|
|
3339
|
+
};
|
|
3340
|
+
if (typeof i.check == "function") {
|
|
3341
|
+
let e;
|
|
3342
|
+
try {
|
|
3343
|
+
e = await i.check(c, o);
|
|
3344
|
+
} catch (e) {
|
|
3345
|
+
throw this.activeOperationId === n && this.clearSolutionFields(), e;
|
|
1356
3346
|
}
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
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]);
|
|
3348
|
+
let t = {};
|
|
3349
|
+
if (e.values && e.status === "Sat") {
|
|
3350
|
+
for (let [n, r] of Object.entries(e.values)) if (typeof r == "number") {
|
|
3351
|
+
if (!Number.isFinite(r)) continue;
|
|
3352
|
+
let e = this.getVarByName(n), i = this.getBoolVarByName(n);
|
|
3353
|
+
e && (e.value = r, this.values.set(e.name, r), s(t, e.name, r)), i && (i.value = !!r, this.values.set(i.name, i.value), s(t, i.name, i.value)), !e && !i && (this.values.set(n, r), s(t, n, r));
|
|
3354
|
+
} else if (typeof r == "boolean") {
|
|
3355
|
+
let e = this.getBoolVarByName(n);
|
|
3356
|
+
e ? (e.value = r, this.values.set(e.name, r), s(t, e.name, r)) : (this.values.set(n, r), s(t, n, r));
|
|
3357
|
+
}
|
|
1366
3358
|
}
|
|
1367
|
-
return {
|
|
1368
|
-
status:
|
|
1369
|
-
values:
|
|
3359
|
+
return this.hasSolutionState = !0, {
|
|
3360
|
+
status: e.status,
|
|
3361
|
+
values: t,
|
|
3362
|
+
unsatCore: this.unsatCore,
|
|
3363
|
+
conflicts: this.conflicts,
|
|
1370
3364
|
runTime: this.runTime
|
|
1371
3365
|
};
|
|
1372
|
-
} finally {
|
|
1373
|
-
this.objective = i, this.sense = a;
|
|
1374
3366
|
}
|
|
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`,
|
|
3414
|
+
sense: "Minimize",
|
|
3415
|
+
objective: new C(new Map(f), 0),
|
|
3416
|
+
constraints: u,
|
|
3417
|
+
variables: [...l.variables, ...d]
|
|
3418
|
+
}, g;
|
|
3419
|
+
try {
|
|
3420
|
+
g = await i.solve(h, o);
|
|
3421
|
+
} catch (e) {
|
|
3422
|
+
throw this.activeOperationId === n && this.clearSolutionFields(), e;
|
|
3423
|
+
}
|
|
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
|
+
}
|
|
3439
|
+
}
|
|
3440
|
+
}
|
|
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);
|
|
3445
|
+
}
|
|
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,
|
|
3451
|
+
runTime: this.runTime
|
|
3452
|
+
};
|
|
3453
|
+
}
|
|
3454
|
+
validateSolution(e = {}) {
|
|
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;
|
|
3473
|
+
}
|
|
3474
|
+
async solveColumnGeneration(e) {
|
|
3475
|
+
let t = await Ue({
|
|
3476
|
+
master: this,
|
|
3477
|
+
...e
|
|
3478
|
+
});
|
|
3479
|
+
return this.decomposition = t, t;
|
|
1375
3480
|
}
|
|
1376
3481
|
};
|
|
1377
3482
|
//#endregion
|
|
1378
|
-
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 };
|