@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 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 in LP format
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
- ## LP Format Reference
199
+ ## Format Reference
102
200
 
103
- The LP format is a human-readable format for optimization problems:
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
- ## Examples
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(largeProblem, { timeLimit: 300 });
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/user/scip.js
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 SCIP Optimization Suite
234
- 2. Compiles with Emscripten to WebAssembly
235
- 3. Bundles JavaScript wrapper
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 | ~5 MB | ~1.5 MB |
242
- | scip.js | ~50 KB | ~15 KB |
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)