0
# Core Model and Optimization
1
2
Central model management that provides the foundation for all optimization workflows in PySCIPOpt. The Model class handles problem setup, solving, and solution access for linear programming, mixed integer programming, and constraint programming problems.
3
4
## Capabilities
5
6
### Model Initialization
7
8
Create and configure optimization models with various settings for different problem types and solving approaches.
9
10
```python { .api }
11
class Model:
12
def __init__(self, problemName='model', defaultPlugins=True, sourceModel=None,
13
origcopy=False, globalcopy=True, enablepricing=False,
14
createscip=True, threadsafe=False):
15
"""
16
Create a new optimization model.
17
18
Parameters:
19
- problemName (str): Name for the problem
20
- defaultPlugins (bool): Include default SCIP plugins
21
- sourceModel (Model): Source model for copying
22
- origcopy (bool): Copy original model state
23
- globalcopy (bool): Perform global copy
24
- enablepricing (bool): Enable column generation
25
- createscip (bool): Create SCIP instance
26
- threadsafe (bool): Enable thread safety
27
"""
28
```
29
30
### Problem Setup and Management
31
32
Core functions for problem lifecycle management including creation, transformation, and cleanup.
33
34
```python { .api }
35
def createProbBasic(self, problemName='model'):
36
"""
37
Create basic problem structure.
38
39
Parameters:
40
- problemName (str): Name for the problem
41
"""
42
43
def freeProb(self):
44
"""Free problem data and reset to initial state."""
45
46
def freeTransform(self):
47
"""Free transformation data while keeping original problem."""
48
49
def includeDefaultPlugins(self):
50
"""Include default SCIP plugins for standard optimization."""
51
```
52
53
### Variable Management
54
55
Comprehensive variable creation and management for different variable types and properties.
56
57
```python { .api }
58
def addVar(self, name='', vtype='C', lb=0.0, ub=None, obj=0.0,
59
pricedVar=False, pricedVarScore=1.0):
60
"""
61
Add a variable to the model.
62
63
Parameters:
64
- name (str): Variable name
65
- vtype (str): Variable type ('C' continuous, 'I' integer, 'B' binary)
66
- lb (float): Lower bound (default: 0.0)
67
- ub (float): Upper bound (default: infinity)
68
- obj (float): Objective coefficient
69
- pricedVar (bool): Is this a priced variable for column generation
70
- pricedVarScore (float): Priority score for priced variables
71
72
Returns:
73
Variable: The created variable object
74
"""
75
76
def getVars(self):
77
"""
78
Get all variables in the model.
79
80
Returns:
81
list: List of all Variable objects
82
"""
83
84
def addVarLocks(self, var, nlocksdown, nlocksup):
85
"""
86
Add locks to prevent variable from being deleted.
87
88
Parameters:
89
- var (Variable): Variable to lock
90
- nlocksdown (int): Number of down locks
91
- nlocksup (int): Number of up locks
92
"""
93
```
94
95
### Constraint Management
96
97
Add and manage constraints with various properties and settings.
98
99
```python { .api }
100
def addCons(self, cons, name='', initial=True, separate=True,
101
enforce=True, check=True, propagate=True, local=False,
102
modifiable=False, dynamic=False, removable=False,
103
stickingatnode=False):
104
"""
105
Add a constraint to the model.
106
107
Parameters:
108
- cons: Constraint expression or ExprCons object
109
- name (str): Constraint name
110
- initial (bool): Should constraint be in initial LP relaxation
111
- separate (bool): Should constraint be subject to separation
112
- enforce (bool): Should constraint be enforced during node processing
113
- check (bool): Should constraint be checked for feasibility
114
- propagate (bool): Should constraint be subject to propagation
115
- local (bool): Is constraint only valid for current subtree
116
- modifiable (bool): Can constraint be modified during solution process
117
- dynamic (bool): Can constraint be added during solution process
118
- removable (bool): Can constraint be removed during solution process
119
- stickingatnode (bool): Should constraint remain at node even if it can be removed
120
121
Returns:
122
Constraint: The created constraint object
123
"""
124
125
def addConss(self, conss, **kwargs):
126
"""
127
Add multiple constraints to the model.
128
129
Parameters:
130
- conss (list): List of constraints
131
- **kwargs: Additional constraint properties (same as addCons)
132
133
Returns:
134
list: List of created Constraint objects
135
"""
136
137
def addConsCoeff(self, cons, var, coeff):
138
"""
139
Add coefficient to existing linear constraint.
140
141
Parameters:
142
- cons (Constraint): Constraint to modify
143
- var (Variable): Variable to add
144
- coeff (float): Coefficient value
145
"""
146
```
147
148
### Objective Function Management
149
150
Set and modify objective functions with different optimization senses.
151
152
```python { .api }
153
def setObjective(self, coeffs, sense='minimize', clear='true'):
154
"""
155
Set the objective function.
156
157
Parameters:
158
- coeffs: Objective expression (Expr, dict, or list)
159
- sense (str): Optimization sense ('minimize' or 'maximize')
160
- clear (str): Clear existing objective ('true' or 'false')
161
"""
162
163
def setMinimize(self):
164
"""Set optimization sense to minimization."""
165
166
def setMaximize(self):
167
"""Set optimization sense to maximization."""
168
169
def getObjective(self):
170
"""
171
Get current objective expression.
172
173
Returns:
174
Expr: Current objective expression
175
"""
176
177
def getObjectiveSense(self):
178
"""
179
Get current optimization sense.
180
181
Returns:
182
str: 'minimize' or 'maximize'
183
"""
184
185
def setObjlimit(self, objlimit):
186
"""
187
Set objective limit for early termination.
188
189
Parameters:
190
- objlimit (float): Objective value limit
191
"""
192
193
def getObjlimit(self):
194
"""
195
Get current objective limit.
196
197
Returns:
198
float: Current objective limit
199
"""
200
201
def addObjoffset(self, offset, solutions=False):
202
"""
203
Add offset to objective function.
204
205
Parameters:
206
- offset (float): Offset value to add
207
- solutions (bool): Apply offset to existing solutions
208
"""
209
```
210
211
### Solving and Optimization
212
213
Core solving functionality with different solving methods and output control.
214
215
```python { .api }
216
def optimize(self):
217
"""
218
Solve the optimization problem.
219
220
This is the main solving method that runs the complete SCIP
221
optimization process including presolving, LP solving, and
222
branch-and-bound.
223
"""
224
225
def solve(self):
226
"""
227
Alternative solving method (alias for optimize).
228
"""
229
230
def hideOutput(self):
231
"""
232
Suppress solver output during optimization.
233
"""
234
```
235
236
### Solution Access
237
238
Retrieve optimization results, variable values, and solution information.
239
240
```python { .api }
241
def getBestSol(self):
242
"""
243
Get the best solution found.
244
245
Returns:
246
Solution: Best solution object, or None if no solution found
247
"""
248
249
def getObjVal(self):
250
"""
251
Get objective value of best solution.
252
253
Returns:
254
float: Objective value
255
256
Raises:
257
Exception: If no solution available
258
"""
259
260
def getVal(self, var):
261
"""
262
Get variable value in best solution.
263
264
Parameters:
265
- var (Variable): Variable to query
266
267
Returns:
268
float: Variable value in solution
269
270
Raises:
271
Exception: If no solution available or variable not found
272
"""
273
274
def getStatus(self):
275
"""
276
Get current solver status.
277
278
Returns:
279
str: Status string ('optimal', 'infeasible', 'unbounded',
280
'timelimit', 'nodelimit', etc.)
281
"""
282
```
283
284
### Statistics and Information
285
286
Access detailed solving statistics and performance information.
287
288
```python { .api }
289
def getTotalTime(self):
290
"""
291
Get total solving time including presolving.
292
293
Returns:
294
float: Total time in seconds
295
"""
296
297
def getSolvingTime(self):
298
"""
299
Get pure solving time excluding presolving.
300
301
Returns:
302
float: Solving time in seconds
303
"""
304
305
def getReadingTime(self):
306
"""
307
Get time spent reading problem files.
308
309
Returns:
310
float: Reading time in seconds
311
"""
312
313
def getPresolvingTime(self):
314
"""
315
Get time spent in presolving.
316
317
Returns:
318
float: Presolving time in seconds
319
"""
320
321
def getNNodes(self):
322
"""
323
Get number of processed branch-and-bound nodes.
324
325
Returns:
326
int: Number of processed nodes
327
"""
328
329
def getNTotalNodes(self):
330
"""
331
Get total number of branch-and-bound nodes.
332
333
Returns:
334
int: Total number of nodes
335
"""
336
337
def getGap(self):
338
"""
339
Get optimality gap (relative difference between best bounds).
340
341
Returns:
342
float: Gap as percentage (0.0 = optimal, 1.0 = 100% gap)
343
"""
344
345
def getDepth(self):
346
"""
347
Get current depth in branch-and-bound tree.
348
349
Returns:
350
int: Current tree depth
351
"""
352
353
def getCurrentNode(self):
354
"""
355
Get current node in branch-and-bound tree.
356
357
Returns:
358
Node: Current node object
359
"""
360
```
361
362
### File I/O Operations
363
364
Read and write optimization problems in various formats.
365
366
```python { .api }
367
def readProblem(self, filename, extension=None):
368
"""
369
Read problem from file.
370
371
Parameters:
372
- filename (str): Path to problem file
373
- extension (str): File format extension (auto-detected if None)
374
375
Supported formats: .lp, .mps, .cip, .zpl, .pip, .osil, .wbo, .opb
376
"""
377
378
def writeProblem(self, filename='model.cip', trans=False, genericnames=False):
379
"""
380
Write problem to file.
381
382
Parameters:
383
- filename (str): Output filename with extension
384
- trans (bool): Write transformed problem
385
- genericnames (bool): Use generic variable/constraint names
386
"""
387
```
388
389
### Numerical Methods and Tolerances
390
391
Access numerical constants and tolerance checking functions.
392
393
```python { .api }
394
def infinity(self):
395
"""
396
Get SCIP's infinity value.
397
398
Returns:
399
float: Infinity value used by SCIP
400
"""
401
402
def epsilon(self):
403
"""
404
Get SCIP's epsilon (smallest meaningful difference).
405
406
Returns:
407
float: Epsilon value
408
"""
409
410
def feastol(self):
411
"""
412
Get feasibility tolerance.
413
414
Returns:
415
float: Feasibility tolerance
416
"""
417
418
def isZero(self, value):
419
"""
420
Test if value is considered zero.
421
422
Parameters:
423
- value (float): Value to test
424
425
Returns:
426
bool: True if value is zero within tolerance
427
"""
428
429
def isFeasZero(self, value):
430
"""
431
Test if value is feasibly zero.
432
433
Parameters:
434
- value (float): Value to test
435
436
Returns:
437
bool: True if value is feasibly zero
438
"""
439
440
def isInfinity(self, value):
441
"""
442
Test if value is infinity.
443
444
Parameters:
445
- value (float): Value to test
446
447
Returns:
448
bool: True if value is infinity
449
"""
450
451
def isEQ(self, val1, val2):
452
"""
453
Test if two values are equal within tolerance.
454
455
Parameters:
456
- val1 (float): First value
457
- val2 (float): Second value
458
459
Returns:
460
bool: True if values are equal within tolerance
461
"""
462
463
def isFeasEQ(self, val1, val2):
464
"""
465
Test if two values are feasibly equal.
466
467
Parameters:
468
- val1 (float): First value
469
- val2 (float): Second value
470
471
Returns:
472
bool: True if values are feasibly equal
473
"""
474
475
def isLE(self, val1, val2):
476
"""
477
Test if first value is less than or equal to second.
478
479
Parameters:
480
- val1 (float): First value
481
- val2 (float): Second value
482
483
Returns:
484
bool: True if val1 <= val2 within tolerance
485
"""
486
487
def isGE(self, val1, val2):
488
"""
489
Test if first value is greater than or equal to second.
490
491
Parameters:
492
- val1 (float): First value
493
- val2 (float): Second value
494
495
Returns:
496
bool: True if val1 >= val2 within tolerance
497
"""
498
```
499
500
## Usage Examples
501
502
### Basic Linear Programming
503
504
```python
505
from pyscipopt import Model
506
507
# Create model
508
model = Model("linear_program")
509
510
# Add variables
511
x1 = model.addVar(name="x1", lb=0)
512
x2 = model.addVar(name="x2", lb=0)
513
514
# Add constraints
515
model.addCons(2*x1 + x2 <= 4, name="constraint1")
516
model.addCons(x1 + 2*x2 <= 4, name="constraint2")
517
518
# Set objective
519
model.setObjective(x1 + x2, "maximize")
520
521
# Solve
522
model.optimize()
523
524
# Get results
525
if model.getStatus() == 'optimal':
526
print(f"Optimal value: {model.getObjVal()}")
527
print(f"x1 = {model.getVal(x1)}")
528
print(f"x2 = {model.getVal(x2)}")
529
```
530
531
### Mixed Integer Programming
532
533
```python
534
from pyscipopt import Model
535
536
# Create model
537
model = Model("integer_program")
538
539
# Add integer variables
540
x = model.addVar(name="x", vtype="I", lb=0, ub=10)
541
y = model.addVar(name="y", vtype="I", lb=0, ub=10)
542
543
# Add binary variable
544
z = model.addVar(name="z", vtype="B")
545
546
# Add constraints
547
model.addCons(3*x + 2*y <= 15, name="resource")
548
model.addCons(x + y >= 2*z, name="logic")
549
550
# Set objective
551
model.setObjective(2*x + 3*y + z, "maximize")
552
553
# Solve
554
model.optimize()
555
556
# Check solution
557
if model.getStatus() == 'optimal':
558
print(f"Solution: x={model.getVal(x)}, y={model.getVal(y)}, z={model.getVal(z)}")
559
print(f"Gap: {model.getGap():.2%}")
560
print(f"Nodes: {model.getNNodes()}")
561
```
562
563
## Error Handling
564
565
### Common Exceptions
566
567
PySCIPOpt may raise exceptions in various scenarios:
568
569
- **No Solution Available**: Methods like `getObjVal()` and `getVal()` raise exceptions when called before a solution is found or when the problem is infeasible
570
- **Invalid Parameters**: Setting invalid parameter values or using invalid parameter names
571
- **File I/O Errors**: Problems reading or writing files with `readProblem()` or `writeProblem()`
572
- **Memory Errors**: Insufficient memory for large problems
573
- **SCIP Internal Errors**: Underlying SCIP solver errors
574
575
### Error Handling Patterns
576
577
```python
578
from pyscipopt import Model
579
580
model = Model("error_handling_example")
581
582
# Safe solution access
583
try:
584
model.optimize()
585
586
if model.getStatus() == 'optimal':
587
obj_val = model.getObjVal()
588
print(f"Optimal value: {obj_val}")
589
elif model.getStatus() == 'infeasible':
590
print("Problem is infeasible")
591
elif model.getStatus() == 'timelimit':
592
print("Time limit reached")
593
if model.getNSols() > 0:
594
print(f"Best solution found: {model.getObjVal()}")
595
else:
596
print(f"Solver status: {model.getStatus()}")
597
598
except Exception as e:
599
print(f"Optimization error: {e}")
600
601
# Safe parameter setting
602
try:
603
model.setParam("limits/time", 300.0)
604
model.setParam("display/verblevel", 2)
605
except Exception as e:
606
print(f"Parameter error: {e}")
607
608
# Safe file operations
609
try:
610
model.readProblem("problem.lp")
611
except FileNotFoundError:
612
print("Problem file not found")
613
except Exception as e:
614
print(f"File reading error: {e}")
615
```