@areb0s/scip.js 1.0.8 → 1.0.9
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.md +152 -44
- package/dist/scip-core.js +1 -1
- package/dist/scip-wrapper.js +33 -17
- package/dist/scip.js +184 -25
- package/dist/scip.js.map +2 -2
- package/dist/scip.min.js +11 -11
- package/dist/scip.min.js.map +3 -3
- package/dist/scip.wasm +0 -0
- package/dist/types.d.ts +8 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
**SCIP Optimization Solver compiled to WebAssembly**
|
|
4
4
|
|
|
5
|
-
Solve Linear Programming (LP), Mixed Integer Programming (MIP), and Mixed Integer Nonlinear Programming (MINLP) problems directly in the browser or Node.js.
|
|
5
|
+
Solve Linear Programming (LP), Mixed Integer Programming (MIP), and **Mixed Integer Nonlinear Programming (MINLP)** problems directly in the browser or Node.js.
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
9
9
|
- **LP**: Linear Programming
|
|
10
10
|
- **MIP**: Mixed Integer Programming (binary, integer variables)
|
|
11
|
-
- **MINLP**: Mixed Integer Nonlinear Programming
|
|
11
|
+
- **MINLP**: Mixed Integer Nonlinear Programming (quadratic, polynomial, nonlinear constraints)
|
|
12
|
+
- **ZIMPL**: Full ZIMPL modeling language support for complex problems
|
|
12
13
|
- **Zero Dependencies**: Pure WebAssembly, no native bindings
|
|
13
14
|
- **Browser & Node.js**: Works everywhere JavaScript runs
|
|
14
15
|
- **Web Worker Support**: Non-blocking solver for long computations
|
|
@@ -30,10 +31,11 @@ Or use via CDN:
|
|
|
30
31
|
|
|
31
32
|
## Quick Start
|
|
32
33
|
|
|
34
|
+
### Linear Programming (LP Format)
|
|
35
|
+
|
|
33
36
|
```javascript
|
|
34
37
|
import SCIP from 'scip.js';
|
|
35
38
|
|
|
36
|
-
// Solve a linear programming problem
|
|
37
39
|
const result = await SCIP.solve(`
|
|
38
40
|
Minimize
|
|
39
41
|
obj: 2 x + 3 y
|
|
@@ -51,6 +53,98 @@ console.log(result.objective); // 7.0
|
|
|
51
53
|
console.log(result.variables); // { x: 1, y: 3 }
|
|
52
54
|
```
|
|
53
55
|
|
|
56
|
+
### Nonlinear Programming (ZIMPL Format)
|
|
57
|
+
|
|
58
|
+
For **MINLP** and nonlinear problems, use ZIMPL format:
|
|
59
|
+
|
|
60
|
+
```javascript
|
|
61
|
+
import SCIP from 'scip.js';
|
|
62
|
+
|
|
63
|
+
// Quadratic optimization: minimize x² + y²
|
|
64
|
+
const result = await SCIP.solve(`
|
|
65
|
+
var x >= 0 <= 10;
|
|
66
|
+
var y >= 0 <= 10;
|
|
67
|
+
|
|
68
|
+
minimize cost: x * x + y * y;
|
|
69
|
+
|
|
70
|
+
subto c1: x + y >= 2;
|
|
71
|
+
`, { format: 'zpl' });
|
|
72
|
+
|
|
73
|
+
console.log(result.status); // 'optimal'
|
|
74
|
+
console.log(result.objective); // 2.0
|
|
75
|
+
console.log(result.variables); // { x: 1, y: 1 }
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## MINLP Examples
|
|
79
|
+
|
|
80
|
+
### Quadratic Programming
|
|
81
|
+
|
|
82
|
+
```javascript
|
|
83
|
+
// Portfolio optimization with risk (quadratic)
|
|
84
|
+
const result = await SCIP.solve(`
|
|
85
|
+
set ASSETS := { "A", "B", "C" };
|
|
86
|
+
|
|
87
|
+
param return[ASSETS] := <"A"> 0.12, <"B"> 0.08, <"C"> 0.15;
|
|
88
|
+
param risk[ASSETS] := <"A"> 0.20, <"B"> 0.10, <"C"> 0.30;
|
|
89
|
+
|
|
90
|
+
var x[ASSETS] >= 0 <= 1;
|
|
91
|
+
|
|
92
|
+
maximize portfolio_return:
|
|
93
|
+
sum <a> in ASSETS: return[a] * x[a]
|
|
94
|
+
- 0.5 * sum <a> in ASSETS: risk[a] * x[a] * x[a];
|
|
95
|
+
|
|
96
|
+
subto budget: sum <a> in ASSETS: x[a] == 1;
|
|
97
|
+
`, { format: 'zpl' });
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Mixed Integer Nonlinear (MINLP)
|
|
101
|
+
|
|
102
|
+
```javascript
|
|
103
|
+
// Facility location with economies of scale
|
|
104
|
+
const result = await SCIP.solve(`
|
|
105
|
+
set FACILITIES := { 1 to 5 };
|
|
106
|
+
set CUSTOMERS := { 1 to 10 };
|
|
107
|
+
|
|
108
|
+
param demand[CUSTOMERS] := <1> 10, <2> 15, <3> 20, <4> 12, <5> 18,
|
|
109
|
+
<6> 8, <7> 25, <8> 14, <9> 16, <10> 11;
|
|
110
|
+
|
|
111
|
+
var open[FACILITIES] binary; # 1 if facility is open
|
|
112
|
+
var flow[FACILITIES * CUSTOMERS] >= 0; # amount shipped
|
|
113
|
+
var capacity[FACILITIES] >= 0 <= 100; # facility capacity
|
|
114
|
+
|
|
115
|
+
minimize total_cost:
|
|
116
|
+
sum <f> in FACILITIES: 1000 * open[f] # fixed cost
|
|
117
|
+
+ sum <f> in FACILITIES: 50 * sqrt(capacity[f]) # capacity cost (nonlinear)
|
|
118
|
+
+ sum <f,c> in FACILITIES * CUSTOMERS: 2 * flow[f,c]; # transport cost
|
|
119
|
+
|
|
120
|
+
subto satisfy_demand:
|
|
121
|
+
forall <c> in CUSTOMERS:
|
|
122
|
+
sum <f> in FACILITIES: flow[f,c] >= demand[c];
|
|
123
|
+
|
|
124
|
+
subto capacity_limit:
|
|
125
|
+
forall <f> in FACILITIES:
|
|
126
|
+
sum <c> in CUSTOMERS: flow[f,c] <= capacity[f] * open[f];
|
|
127
|
+
`, { format: 'zpl' });
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Polynomial Constraints
|
|
131
|
+
|
|
132
|
+
```javascript
|
|
133
|
+
// Nonlinear constraints with polynomials
|
|
134
|
+
const result = await SCIP.solve(`
|
|
135
|
+
var x >= -10 <= 10;
|
|
136
|
+
var y >= -10 <= 10;
|
|
137
|
+
|
|
138
|
+
minimize obj: x + y;
|
|
139
|
+
|
|
140
|
+
# Polynomial constraint: x³ + y³ >= 8
|
|
141
|
+
subto poly: x * x * x + y * y * y >= 8;
|
|
142
|
+
|
|
143
|
+
# Circle constraint: x² + y² <= 25
|
|
144
|
+
subto circle: x * x + y * y <= 25;
|
|
145
|
+
`, { format: 'zpl' });
|
|
146
|
+
```
|
|
147
|
+
|
|
54
148
|
## API Reference
|
|
55
149
|
|
|
56
150
|
### `SCIP.solve(problem, options?)`
|
|
@@ -58,9 +152,13 @@ console.log(result.variables); // { x: 1, y: 3 }
|
|
|
58
152
|
Solve an optimization problem.
|
|
59
153
|
|
|
60
154
|
**Parameters:**
|
|
61
|
-
- `problem` (string): Problem
|
|
155
|
+
- `problem` (string): Problem definition
|
|
62
156
|
- `options` (object, optional):
|
|
63
|
-
- `format`: `'lp'` | `'mps'` | `'zpl'` (default: `'lp'`)
|
|
157
|
+
- `format`: `'lp'` | `'mps'` | `'zpl'` | `'cip'` (default: `'lp'`)
|
|
158
|
+
- `'lp'`: LP format (linear problems only)
|
|
159
|
+
- `'mps'`: MPS format (linear problems only)
|
|
160
|
+
- `'zpl'`: **ZIMPL format (supports MINLP, nonlinear)**
|
|
161
|
+
- `'cip'`: CIP format (SCIP's native format)
|
|
64
162
|
- `timeLimit`: Time limit in seconds (default: 3600)
|
|
65
163
|
- `gap`: Relative MIP gap tolerance (e.g., 0.01 for 1%)
|
|
66
164
|
- `verbose`: Enable verbose output (default: false)
|
|
@@ -98,9 +196,9 @@ Initialize the SCIP WASM module. Called automatically on first solve.
|
|
|
98
196
|
|
|
99
197
|
Get SCIP version information.
|
|
100
198
|
|
|
101
|
-
##
|
|
199
|
+
## Format Reference
|
|
102
200
|
|
|
103
|
-
|
|
201
|
+
### LP Format (Linear Only)
|
|
104
202
|
|
|
105
203
|
```
|
|
106
204
|
\ Comments start with backslash
|
|
@@ -110,12 +208,10 @@ Minimize (or Maximize)
|
|
|
110
208
|
Subject To
|
|
111
209
|
constraint1: x + y >= 10
|
|
112
210
|
constraint2: x - y <= 5
|
|
113
|
-
constraint3: x + 2 y + 3 z = 15
|
|
114
211
|
|
|
115
212
|
Bounds
|
|
116
213
|
0 <= x <= 100
|
|
117
214
|
y >= 0
|
|
118
|
-
z free
|
|
119
215
|
|
|
120
216
|
General (Integer variables)
|
|
121
217
|
x
|
|
@@ -126,7 +222,35 @@ Binary (0-1 variables)
|
|
|
126
222
|
End
|
|
127
223
|
```
|
|
128
224
|
|
|
129
|
-
|
|
225
|
+
### ZIMPL Format (Supports Nonlinear)
|
|
226
|
+
|
|
227
|
+
```zimpl
|
|
228
|
+
# Sets
|
|
229
|
+
set ITEMS := { "apple", "banana", "orange" };
|
|
230
|
+
|
|
231
|
+
# Parameters
|
|
232
|
+
param weight[ITEMS] := <"apple"> 2, <"banana"> 3, <"orange"> 4;
|
|
233
|
+
param value[ITEMS] := <"apple"> 10, <"banana"> 15, <"orange"> 20;
|
|
234
|
+
|
|
235
|
+
# Variables
|
|
236
|
+
var x[ITEMS] binary; # binary variable
|
|
237
|
+
var y >= 0 <= 100; # continuous variable
|
|
238
|
+
var z integer >= 0 <= 10; # integer variable
|
|
239
|
+
|
|
240
|
+
# Objective (can include nonlinear terms)
|
|
241
|
+
maximize profit:
|
|
242
|
+
sum <i> in ITEMS: value[i] * x[i]
|
|
243
|
+
- 0.1 * y * y; # quadratic term
|
|
244
|
+
|
|
245
|
+
# Constraints
|
|
246
|
+
subto capacity:
|
|
247
|
+
sum <i> in ITEMS: weight[i] * x[i] <= 10;
|
|
248
|
+
|
|
249
|
+
subto nonlinear_constraint:
|
|
250
|
+
y * y + z * z <= 50; # quadratic constraint
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## More Examples
|
|
130
254
|
|
|
131
255
|
### Linear Programming
|
|
132
256
|
|
|
@@ -159,32 +283,11 @@ const result = await SCIP.maximize(`
|
|
|
159
283
|
// result.objective = 220
|
|
160
284
|
```
|
|
161
285
|
|
|
162
|
-
### Transportation Problem
|
|
163
|
-
|
|
164
|
-
```javascript
|
|
165
|
-
const result = await SCIP.minimize(`
|
|
166
|
-
obj: 8 x11 + 6 x12 + 10 x13 + 9 x21 + 12 x22 + 7 x23
|
|
167
|
-
Subject To
|
|
168
|
-
supply1: x11 + x12 + x13 <= 100
|
|
169
|
-
supply2: x21 + x22 + x23 <= 150
|
|
170
|
-
demand1: x11 + x21 >= 80
|
|
171
|
-
demand2: x12 + x22 >= 70
|
|
172
|
-
demand3: x13 + x23 >= 60
|
|
173
|
-
Bounds
|
|
174
|
-
x11 >= 0
|
|
175
|
-
x12 >= 0
|
|
176
|
-
x13 >= 0
|
|
177
|
-
x21 >= 0
|
|
178
|
-
x22 >= 0
|
|
179
|
-
x23 >= 0
|
|
180
|
-
End
|
|
181
|
-
`);
|
|
182
|
-
```
|
|
183
|
-
|
|
184
286
|
### With Time Limit and Gap
|
|
185
287
|
|
|
186
288
|
```javascript
|
|
187
289
|
const result = await SCIP.solve(problem, {
|
|
290
|
+
format: 'zpl',
|
|
188
291
|
timeLimit: 60, // 60 seconds
|
|
189
292
|
gap: 0.01, // Stop when within 1% of optimal
|
|
190
293
|
verbose: true // Print solver output
|
|
@@ -200,8 +303,11 @@ import { createWorkerSolver } from 'scip.js';
|
|
|
200
303
|
|
|
201
304
|
const solver = await createWorkerSolver();
|
|
202
305
|
|
|
203
|
-
// Solve in background
|
|
204
|
-
const result = await solver.solve(
|
|
306
|
+
// Solve MINLP in background
|
|
307
|
+
const result = await solver.solve(nonlinearProblem, {
|
|
308
|
+
format: 'zpl',
|
|
309
|
+
timeLimit: 300
|
|
310
|
+
});
|
|
205
311
|
|
|
206
312
|
// Clean up when done
|
|
207
313
|
solver.terminate();
|
|
@@ -218,10 +324,10 @@ solver.terminate();
|
|
|
218
324
|
|
|
219
325
|
```bash
|
|
220
326
|
# Clone repository
|
|
221
|
-
git clone https://github.com/
|
|
327
|
+
git clone https://github.com/areb0s/scip.js
|
|
222
328
|
cd scip.js
|
|
223
329
|
|
|
224
|
-
# Build WASM (uses Docker)
|
|
330
|
+
# Build WASM (uses Docker, includes ZIMPL + GMP)
|
|
225
331
|
./build.sh
|
|
226
332
|
|
|
227
333
|
# Output in dist/
|
|
@@ -230,23 +336,23 @@ ls dist/
|
|
|
230
336
|
```
|
|
231
337
|
|
|
232
338
|
The build process:
|
|
233
|
-
1. Downloads
|
|
234
|
-
2.
|
|
235
|
-
3.
|
|
339
|
+
1. Downloads and compiles GMP (for ZIMPL support)
|
|
340
|
+
2. Downloads SCIP Optimization Suite with ZIMPL
|
|
341
|
+
3. Compiles with Emscripten to WebAssembly
|
|
342
|
+
4. Bundles JavaScript wrapper
|
|
236
343
|
|
|
237
344
|
## File Sizes
|
|
238
345
|
|
|
239
346
|
| File | Size | Gzipped |
|
|
240
347
|
|------|------|---------|
|
|
241
|
-
| scip.wasm | ~
|
|
242
|
-
| scip.js | ~
|
|
348
|
+
| scip.wasm | ~8 MB | ~2.5 MB |
|
|
349
|
+
| scip.js | ~60 KB | ~18 KB |
|
|
243
350
|
|
|
244
351
|
## Limitations
|
|
245
352
|
|
|
246
353
|
- **Single-threaded**: WASM runs single-threaded (use Web Workers for parallelism at application level)
|
|
247
354
|
- **Memory**: Limited to ~2GB (WASM 32-bit limit)
|
|
248
355
|
- **No callbacks**: Progress callbacks not yet supported
|
|
249
|
-
- **ZIMPL disabled**: ZIMPL modeling language not included (use LP/MPS format)
|
|
250
356
|
|
|
251
357
|
## Performance
|
|
252
358
|
|
|
@@ -258,6 +364,8 @@ Typical solving times in browser (varies by problem complexity):
|
|
|
258
364
|
| LP | 10,000 | 5,000 | ~5s |
|
|
259
365
|
| MIP | 100 binary | 50 | ~1s |
|
|
260
366
|
| MIP | 1,000 binary | 500 | ~30s |
|
|
367
|
+
| MINLP (quadratic) | 50 | 20 | ~2s |
|
|
368
|
+
| MINLP (polynomial) | 100 | 50 | ~10s |
|
|
261
369
|
|
|
262
370
|
## License
|
|
263
371
|
|
|
@@ -266,11 +374,11 @@ Apache 2.0 (same as SCIP)
|
|
|
266
374
|
## Credits
|
|
267
375
|
|
|
268
376
|
- [SCIP Optimization Suite](https://scipopt.org) - The underlying solver
|
|
377
|
+
- [ZIMPL](https://zimpl.zib.de/) - Modeling language for MINLP
|
|
269
378
|
- [Emscripten](https://emscripten.org) - C++ to WebAssembly compiler
|
|
270
|
-
- [poker-chipper](https://github.com/jstrieb/poker-chipper) - Reference SCIP WASM build
|
|
271
379
|
|
|
272
380
|
## Links
|
|
273
381
|
|
|
274
382
|
- [SCIP Documentation](https://scipopt.org/doc/html/)
|
|
383
|
+
- [ZIMPL User Guide](https://zimpl.zib.de/download/zimpl.pdf)
|
|
275
384
|
- [LP Format Reference](https://www.gurobi.com/documentation/current/refman/lp_format.html)
|
|
276
|
-
- [MPS Format Reference](https://www.gurobi.com/documentation/current/refman/mps_format.html)
|