PySCIPOpt 6.0.0__cp312-cp312-win_amd64.whl → 6.1.0__cp312-cp312-win_amd64.whl

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.
pyscipopt/__init__.py CHANGED
@@ -1,12 +1,12 @@
1
1
  """""" # start delvewheel patch
2
- def _delvewheel_patch_1_11_2():
2
+ def _delvewheel_patch_1_12_0():
3
3
  import os
4
4
  if os.path.isdir(libs_dir := os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, 'pyscipopt.libs'))):
5
5
  os.add_dll_directory(libs_dir)
6
6
 
7
7
 
8
- _delvewheel_patch_1_11_2()
9
- del _delvewheel_patch_1_11_2
8
+ _delvewheel_patch_1_12_0()
9
+ del _delvewheel_patch_1_12_0
10
10
  # end delvewheel patch
11
11
 
12
12
  from ._version import __version__
@@ -15,7 +15,7 @@ from ._version import __version__
15
15
  import os
16
16
  if hasattr(os, 'add_dll_directory'):
17
17
  if os.getenv('SCIPOPTDIR'):
18
- os.add_dll_directory(os.path.join(os.getenv('SCIPOPTDIR').strip('"'), 'bin'))
18
+ os.add_dll_directory(os.path.join(os.environ['SCIPOPTDIR'].strip('"'), 'bin'))
19
19
 
20
20
  # export user-relevant objects:
21
21
  from pyscipopt.Multidict import multidict as multidict
pyscipopt/_version.py CHANGED
@@ -1 +1 @@
1
- __version__: str = '6.0.0'
1
+ __version__: str = '6.1.0'
pyscipopt/benders.pxi CHANGED
@@ -35,8 +35,7 @@ cdef class Benders:
35
35
 
36
36
  def benderscreatesub(self, probnumber):
37
37
  '''creates the subproblems and registers it with the Benders decomposition struct '''
38
- print("python error in benderscreatesub: this method needs to be implemented")
39
- return {}
38
+ raise NotImplementedError("benderscreatesub() is a fundamental callback and should be implemented in the derived class")
40
39
 
41
40
  def benderspresubsolve(self, solution, enfotype, checkint):
42
41
  '''sets the pre subproblem solve callback of Benders decomposition '''
@@ -60,8 +59,7 @@ cdef class Benders:
60
59
 
61
60
  def bendersgetvar(self, variable, probnumber):
62
61
  '''Returns the corresponding master or subproblem variable for the given variable. This provides a call back for the variable mapping between the master and subproblems. '''
63
- print("python error in bendersgetvar: this method needs to be implemented")
64
- return {}
62
+ raise NotImplementedError("bendersgetvar() is a fundamental callback and should be implemented in the derived class")
65
63
 
66
64
  # local helper functions for the interface
67
65
  cdef Variable getPyVar(SCIP_VAR* var):
pyscipopt/benderscut.pxi CHANGED
@@ -21,8 +21,7 @@ cdef class Benderscut:
21
21
  pass
22
22
 
23
23
  def benderscutexec(self, solution, probnumber, enfotype):
24
- print("python error in benderscutexec: this method needs to be implemented")
25
- return {}
24
+ raise NotImplementedError("benderscutexec() is a fundamental callback and should be implemented in the derived class")
26
25
 
27
26
  cdef SCIP_RETCODE PyBenderscutCopy (SCIP* scip, SCIP_BENDERS* benders, SCIP_BENDERSCUT* benderscut) noexcept with gil:
28
27
  return SCIP_OKAY
pyscipopt/conshdlr.pxi CHANGED
@@ -55,23 +55,19 @@ cdef class Conshdlr:
55
55
 
56
56
  def consenfolp(self, constraints, nusefulconss, solinfeasible):
57
57
  '''calls enforcing method of constraint handler for LP solution for all constraints added'''
58
- print("python error in consenfolp: this method needs to be implemented")
59
- return {}
58
+ raise NotImplementedError("consenfolp() is a fundamental callback and should be implemented in the derived class")
60
59
 
61
60
  def consenforelax(self, solution, constraints, nusefulconss, solinfeasible):
62
61
  '''calls enforcing method of constraint handler for a relaxation solution for all constraints added'''
63
- print("python error in consenforelax: this method needs to be implemented")
64
- return {}
62
+ raise NotImplementedError("consenforelax() is a fundamental callback and should be implemented in the derived class")
65
63
 
66
64
  def consenfops(self, constraints, nusefulconss, solinfeasible, objinfeasible):
67
65
  '''calls enforcing method of constraint handler for pseudo solution for all constraints added'''
68
- print("python error in consenfops: this method needs to be implemented")
69
- return {}
66
+ raise NotImplementedError("consenfops() is a fundamental callback and should be implemented in the derived class")
70
67
 
71
68
  def conscheck(self, constraints, solution, checkintegrality, checklprows, printreason, completely):
72
69
  '''calls feasibility check method of constraint handler '''
73
- print("python error in conscheck: this method needs to be implemented")
74
- return {}
70
+ raise NotImplementedError("conscheck() is a fundamental callback and should be implemented in the derived class")
75
71
 
76
72
  def consprop(self, constraints, nusefulconss, nmarkedconss, proptiming):
77
73
  '''calls propagation method of constraint handler '''
@@ -89,8 +85,7 @@ cdef class Conshdlr:
89
85
 
90
86
  def conslock(self, constraint, locktype, nlockspos, nlocksneg):
91
87
  '''variable rounding lock method of constraint handler'''
92
- print("python error in conslock: this method needs to be implemented")
93
- return {}
88
+ raise NotImplementedError("conslock() is a fundamental callback and should be implemented in the derived class")
94
89
 
95
90
  def consactive(self, constraint):
96
91
  '''sets activation notification method of constraint handler '''
pyscipopt/event.pxi CHANGED
@@ -34,8 +34,7 @@ cdef class Eventhdlr:
34
34
 
35
35
  def eventexec(self, event):
36
36
  '''calls execution method of event handler '''
37
- print("python error in eventexec: this method needs to be implemented")
38
- return {}
37
+ raise NotImplementedError("eventexec() is a fundamental callback and should be implemented in the derived class")
39
38
 
40
39
 
41
40
  # local helper functions for the interface
pyscipopt/expr.pxi CHANGED
@@ -42,7 +42,20 @@
42
42
  # which should, in princple, modify the expr. However, since we do not implement __isub__, __sub__
43
43
  # gets called (I guess) and so a copy is returned.
44
44
  # Modifying the expression directly would be a bug, given that the expression might be re-used by the user. </pre>
45
- include "matrix.pxi"
45
+ import math
46
+ from typing import TYPE_CHECKING
47
+
48
+ from cpython.dict cimport PyDict_Next, PyDict_GetItem
49
+ from cpython.object cimport Py_TYPE
50
+ from cpython.ref cimport PyObject
51
+ from cpython.tuple cimport PyTuple_GET_ITEM
52
+ from pyscipopt.scip cimport Variable, Solution
53
+
54
+ import numpy as np
55
+
56
+
57
+ if TYPE_CHECKING:
58
+ double = float
46
59
 
47
60
 
48
61
  def _is_number(e):
@@ -61,7 +74,7 @@ def _expr_richcmp(self, other, op):
61
74
  return (self - other) <= 0.0
62
75
  elif _is_number(other):
63
76
  return ExprCons(self, rhs=float(other))
64
- elif isinstance(other, MatrixExpr):
77
+ elif isinstance(other, np.ndarray):
65
78
  return _expr_richcmp(other, self, 5)
66
79
  else:
67
80
  raise TypeError(f"Unsupported type {type(other)}")
@@ -70,7 +83,7 @@ def _expr_richcmp(self, other, op):
70
83
  return (self - other) >= 0.0
71
84
  elif _is_number(other):
72
85
  return ExprCons(self, lhs=float(other))
73
- elif isinstance(other, MatrixExpr):
86
+ elif isinstance(other, np.ndarray):
74
87
  return _expr_richcmp(other, self, 1)
75
88
  else:
76
89
  raise TypeError(f"Unsupported type {type(other)}")
@@ -79,7 +92,7 @@ def _expr_richcmp(self, other, op):
79
92
  return (self - other) == 0.0
80
93
  elif _is_number(other):
81
94
  return ExprCons(self, lhs=float(other), rhs=float(other))
82
- elif isinstance(other, MatrixExpr):
95
+ elif isinstance(other, np.ndarray):
83
96
  return _expr_richcmp(other, self, 2)
84
97
  else:
85
98
  raise TypeError(f"Unsupported type {type(other)}")
@@ -87,35 +100,83 @@ def _expr_richcmp(self, other, op):
87
100
  raise NotImplementedError("Can only support constraints with '<=', '>=', or '=='.")
88
101
 
89
102
 
90
- class Term:
103
+ cdef class Term:
91
104
  '''This is a monomial term'''
92
105
 
93
- __slots__ = ('vartuple', 'ptrtuple', 'hashval')
106
+ cdef readonly tuple vartuple
107
+ cdef readonly tuple ptrtuple
108
+ cdef Py_ssize_t hashval
94
109
 
95
- def __init__(self, *vartuple):
110
+ def __init__(self, *vartuple: Variable):
96
111
  self.vartuple = tuple(sorted(vartuple, key=lambda v: v.ptr()))
97
112
  self.ptrtuple = tuple(v.ptr() for v in self.vartuple)
98
- self.hashval = sum(self.ptrtuple)
113
+ self.hashval = <Py_ssize_t>hash(self.ptrtuple)
99
114
 
100
115
  def __getitem__(self, idx):
101
116
  return self.vartuple[idx]
102
117
 
103
- def __hash__(self):
118
+ def __hash__(self) -> Py_ssize_t:
104
119
  return self.hashval
105
120
 
106
- def __eq__(self, other):
121
+ def __eq__(self, other: Term):
107
122
  return self.ptrtuple == other.ptrtuple
108
123
 
109
124
  def __len__(self):
110
125
  return len(self.vartuple)
111
126
 
112
- def __add__(self, other):
113
- both = self.vartuple + other.vartuple
114
- return Term(*both)
127
+ def __mul__(self, Term other):
128
+ # NOTE: This merge algorithm requires a sorted `Term.vartuple`.
129
+ # This should be ensured in the constructor of Term.
130
+ cdef int n1 = len(self)
131
+ cdef int n2 = len(other)
132
+ if n1 == 0: return other
133
+ if n2 == 0: return self
134
+
135
+ cdef list vartuple = [None] * (n1 + n2)
136
+ cdef int i = 0, j = 0, k = 0
137
+ cdef Variable var1, var2
138
+ while i < n1 and j < n2:
139
+ var1 = <Variable>PyTuple_GET_ITEM(self.vartuple, i)
140
+ var2 = <Variable>PyTuple_GET_ITEM(other.vartuple, j)
141
+ if var1.ptr() <= var2.ptr():
142
+ vartuple[k] = var1
143
+ i += 1
144
+ else:
145
+ vartuple[k] = var2
146
+ j += 1
147
+ k += 1
148
+ while i < n1:
149
+ vartuple[k] = <Variable>PyTuple_GET_ITEM(self.vartuple, i)
150
+ i += 1
151
+ k += 1
152
+ while j < n2:
153
+ vartuple[k] = <Variable>PyTuple_GET_ITEM(other.vartuple, j)
154
+ j += 1
155
+ k += 1
156
+
157
+ cdef Term res = Term.__new__(Term)
158
+ res.vartuple = tuple(vartuple)
159
+ res.ptrtuple = tuple(v.ptr() for v in res.vartuple)
160
+ res.hashval = <Py_ssize_t>hash(res.ptrtuple)
161
+ return res
115
162
 
116
163
  def __repr__(self):
117
164
  return 'Term(%s)' % ', '.join([str(v) for v in self.vartuple])
118
165
 
166
+ cpdef double _evaluate(self, Solution sol) except *:
167
+ cdef double res = 1.0
168
+ cdef SCIP* scip_ptr = sol.scip
169
+ cdef SCIP_SOL* sol_ptr = sol.sol
170
+ cdef int i = 0, n = len(self)
171
+ cdef Variable var
172
+
173
+ for i in range(n):
174
+ var = <Variable>self.vartuple[i]
175
+ res *= SCIPgetSolVal(scip_ptr, sol_ptr, var.scip_var)
176
+ if res == 0: # early stop
177
+ return 0.0
178
+ return res
179
+
119
180
 
120
181
  CONST = Term()
121
182
 
@@ -144,7 +205,7 @@ def buildGenExprObj(expr):
144
205
  sumexpr += coef * prodexpr
145
206
  return sumexpr
146
207
 
147
- elif isinstance(expr, MatrixExpr):
208
+ elif isinstance(expr, np.ndarray):
148
209
  GenExprs = np.empty(expr.shape, dtype=object)
149
210
  for idx in np.ndindex(expr.shape):
150
211
  GenExprs[idx] = buildGenExprObj(expr[idx])
@@ -157,7 +218,7 @@ def buildGenExprObj(expr):
157
218
  ##@details Polynomial expressions of variables with operator overloading. \n
158
219
  #See also the @ref ExprDetails "description" in the expr.pxi.
159
220
  cdef class Expr:
160
-
221
+
161
222
  def __init__(self, terms=None):
162
223
  '''terms is a dict of variables to coefficients.
163
224
 
@@ -175,20 +236,12 @@ cdef class Expr:
175
236
  def __iter__(self):
176
237
  return iter(self.terms)
177
238
 
178
- def __next__(self):
179
- try: return next(self.terms)
180
- except: raise StopIteration
181
-
182
239
  def __abs__(self):
183
240
  return abs(buildGenExprObj(self))
184
241
 
185
242
  def __add__(self, other):
186
243
  left = self
187
244
  right = other
188
-
189
- if _is_number(self):
190
- assert isinstance(other, Expr)
191
- left,right = right,left
192
245
  terms = left.terms.copy()
193
246
 
194
247
  if isinstance(right, Expr):
@@ -200,7 +253,7 @@ cdef class Expr:
200
253
  terms[CONST] = terms.get(CONST, 0.0) + c
201
254
  elif isinstance(right, GenExpr):
202
255
  return buildGenExprObj(left) + right
203
- elif isinstance(right, MatrixExpr):
256
+ elif isinstance(right, np.ndarray):
204
257
  return right + left
205
258
  else:
206
259
  raise TypeError(f"Unsupported type {type(right)}")
@@ -225,22 +278,35 @@ cdef class Expr:
225
278
  return self
226
279
 
227
280
  def __mul__(self, other):
228
- if isinstance(other, MatrixExpr):
281
+ if isinstance(other, np.ndarray):
229
282
  return other * self
230
283
 
284
+ cdef dict res = {}
285
+ cdef Py_ssize_t pos1 = <Py_ssize_t>0, pos2 = <Py_ssize_t>0
286
+ cdef PyObject *k1_ptr = NULL
287
+ cdef PyObject *v1_ptr = NULL
288
+ cdef PyObject *k2_ptr = NULL
289
+ cdef PyObject *v2_ptr = NULL
290
+ cdef PyObject *old_v_ptr = NULL
291
+ cdef Term child
292
+ cdef double prod_v
293
+
231
294
  if _is_number(other):
232
295
  f = float(other)
233
296
  return Expr({v:f*c for v,c in self.terms.items()})
234
- elif _is_number(self):
235
- f = float(self)
236
- return Expr({v:f*c for v,c in other.terms.items()})
297
+
237
298
  elif isinstance(other, Expr):
238
- terms = {}
239
- for v1, c1 in self.terms.items():
240
- for v2, c2 in other.terms.items():
241
- v = v1 + v2
242
- terms[v] = terms.get(v, 0.0) + c1 * c2
243
- return Expr(terms)
299
+ while PyDict_Next(self.terms, &pos1, &k1_ptr, &v1_ptr):
300
+ pos2 = <Py_ssize_t>0
301
+ while PyDict_Next(other.terms, &pos2, &k2_ptr, &v2_ptr):
302
+ child = (<Term>k1_ptr) * (<Term>k2_ptr)
303
+ prod_v = (<double>(<object>v1_ptr)) * (<double>(<object>v2_ptr))
304
+ if (old_v_ptr := PyDict_GetItem(res, child)) != NULL:
305
+ res[child] = <double>(<object>old_v_ptr) + prod_v
306
+ else:
307
+ res[child] = prod_v
308
+ return Expr(res)
309
+
244
310
  elif isinstance(other, GenExpr):
245
311
  return buildGenExprObj(self) * other
246
312
  else:
@@ -255,11 +321,7 @@ cdef class Expr:
255
321
 
256
322
  def __rtruediv__(self, other):
257
323
  ''' other / self '''
258
- if _is_number(self):
259
- f = 1.0/float(self)
260
- return f * other
261
- otherexpr = buildGenExprObj(other)
262
- return otherexpr.__truediv__(self)
324
+ return buildGenExprObj(other) / self
263
325
 
264
326
  def __pow__(self, other, modulo):
265
327
  if float(other).is_integer() and other >= 0:
@@ -318,6 +380,20 @@ cdef class Expr:
318
380
  else:
319
381
  return max(len(v) for v in self.terms)
320
382
 
383
+ cpdef double _evaluate(self, Solution sol) except *:
384
+ cdef double res = 0
385
+ cdef Py_ssize_t pos = <Py_ssize_t>0
386
+ cdef PyObject* key_ptr
387
+ cdef PyObject* val_ptr
388
+ cdef Term term
389
+ cdef double coef
390
+
391
+ while PyDict_Next(self.terms, &pos, &key_ptr, &val_ptr):
392
+ term = <Term>key_ptr
393
+ coef = <double>(<object>val_ptr)
394
+ res += coef * term._evaluate(sol)
395
+ return res
396
+
321
397
 
322
398
  cdef class ExprCons:
323
399
  '''Constraints with a polynomial expressions and lower/upper bounds.'''
@@ -427,10 +503,10 @@ Operator = Op()
427
503
  #
428
504
  #See also the @ref ExprDetails "description" in the expr.pxi.
429
505
  cdef class GenExpr:
506
+
430
507
  cdef public _op
431
508
  cdef public children
432
509
 
433
-
434
510
  def __init__(self): # do we need it
435
511
  ''' '''
436
512
 
@@ -438,7 +514,7 @@ cdef class GenExpr:
438
514
  return UnaryExpr(Operator.fabs, self)
439
515
 
440
516
  def __add__(self, other):
441
- if isinstance(other, MatrixExpr):
517
+ if isinstance(other, np.ndarray):
442
518
  return other + self
443
519
 
444
520
  left = buildGenExprObj(self)
@@ -496,7 +572,7 @@ cdef class GenExpr:
496
572
  # return self
497
573
 
498
574
  def __mul__(self, other):
499
- if isinstance(other, MatrixExpr):
575
+ if isinstance(other, np.ndarray):
500
576
  return other * self
501
577
 
502
578
  left = buildGenExprObj(self)
@@ -610,6 +686,20 @@ cdef class GenExpr:
610
686
  '''returns operator of GenExpr'''
611
687
  return self._op
612
688
 
689
+ cdef GenExpr copy(self, bool copy = True):
690
+ cdef object cls = <type>Py_TYPE(self)
691
+ cdef GenExpr res = cls.__new__(cls)
692
+ res._op = self._op
693
+ res.children = self.children.copy() if copy else self.children
694
+ if cls is SumExpr:
695
+ (<SumExpr>res).constant = (<SumExpr>self).constant
696
+ (<SumExpr>res).coefs = (<SumExpr>self).coefs.copy() if copy else (<SumExpr>self).coefs
697
+ if cls is ProdExpr:
698
+ (<ProdExpr>res).constant = (<ProdExpr>self).constant
699
+ elif cls is PowExpr:
700
+ (<PowExpr>res).expo = (<PowExpr>self).expo
701
+ return res
702
+
613
703
 
614
704
  # Sum Expressions
615
705
  cdef class SumExpr(GenExpr):
@@ -625,44 +715,93 @@ cdef class SumExpr(GenExpr):
625
715
  def __repr__(self):
626
716
  return self._op + "(" + str(self.constant) + "," + ",".join(map(lambda child : child.__repr__(), self.children)) + ")"
627
717
 
718
+ cpdef double _evaluate(self, Solution sol) except *:
719
+ cdef double res = self.constant
720
+ cdef int i = 0, n = len(self.children)
721
+ cdef list children = self.children
722
+ cdef list coefs = self.coefs
723
+ for i in range(n):
724
+ res += <double>coefs[i] * (<GenExpr>children[i])._evaluate(sol)
725
+ return res
726
+
727
+
628
728
  # Prod Expressions
629
729
  cdef class ProdExpr(GenExpr):
730
+
630
731
  cdef public constant
732
+
631
733
  def __init__(self):
632
734
  self.constant = 1.0
633
735
  self.children = []
634
736
  self._op = Operator.prod
737
+
635
738
  def __repr__(self):
636
739
  return self._op + "(" + str(self.constant) + "," + ",".join(map(lambda child : child.__repr__(), self.children)) + ")"
637
740
 
741
+ cpdef double _evaluate(self, Solution sol) except *:
742
+ cdef double res = self.constant
743
+ cdef list children = self.children
744
+ cdef int i = 0, n = len(children)
745
+ for i in range(n):
746
+ res *= (<GenExpr>children[i])._evaluate(sol)
747
+ if res == 0: # early stop
748
+ return 0.0
749
+ return res
750
+
751
+
638
752
  # Var Expressions
639
753
  cdef class VarExpr(GenExpr):
754
+
640
755
  cdef public var
756
+
641
757
  def __init__(self, var):
642
758
  self.children = [var]
643
759
  self._op = Operator.varidx
760
+
644
761
  def __repr__(self):
645
762
  return self.children[0].__repr__()
646
763
 
764
+ cpdef double _evaluate(self, Solution sol) except *:
765
+ return (<Expr>self.children[0])._evaluate(sol)
766
+
767
+
647
768
  # Pow Expressions
648
769
  cdef class PowExpr(GenExpr):
770
+
649
771
  cdef public expo
772
+
650
773
  def __init__(self):
651
774
  self.expo = 1.0
652
775
  self.children = []
653
776
  self._op = Operator.power
777
+
654
778
  def __repr__(self):
655
779
  return self._op + "(" + self.children[0].__repr__() + "," + str(self.expo) + ")"
656
780
 
781
+ cpdef double _evaluate(self, Solution sol) except *:
782
+ return (<GenExpr>self.children[0])._evaluate(sol) ** self.expo
783
+
784
+
657
785
  # Exp, Log, Sqrt, Sin, Cos Expressions
658
786
  cdef class UnaryExpr(GenExpr):
659
787
  def __init__(self, op, expr):
660
788
  self.children = []
661
789
  self.children.append(expr)
662
790
  self._op = op
791
+
792
+ def __abs__(self) -> UnaryExpr:
793
+ if self._op == "abs":
794
+ return <UnaryExpr>self.copy()
795
+ return UnaryExpr(Operator.fabs, self)
796
+
663
797
  def __repr__(self):
664
798
  return self._op + "(" + self.children[0].__repr__() + ")"
665
799
 
800
+ cpdef double _evaluate(self, Solution sol) except *:
801
+ cdef double res = (<GenExpr>self.children[0])._evaluate(sol)
802
+ return math.fabs(res) if self._op == "abs" else getattr(math, self._op)(res)
803
+
804
+
666
805
  # class for constant expressions
667
806
  cdef class Constant(GenExpr):
668
807
  cdef public number
@@ -673,6 +812,10 @@ cdef class Constant(GenExpr):
673
812
  def __repr__(self):
674
813
  return str(self.number)
675
814
 
815
+ cpdef double _evaluate(self, Solution sol) except *:
816
+ return self.number
817
+
818
+
676
819
  def exp(expr):
677
820
  """returns expression with exp-function"""
678
821
  if isinstance(expr, MatrixExpr):
pyscipopt/heuristic.pxi CHANGED
@@ -26,8 +26,7 @@ cdef class Heur:
26
26
 
27
27
  def heurexec(self, heurtiming, nodeinfeasible):
28
28
  '''should the heuristic the executed at the given depth, frequency, timing,...'''
29
- print("python error in heurexec: this method needs to be implemented")
30
- return {}
29
+ raise NotImplementedError("heurexec() is a fundamental callback and should be implemented in the derived class")
31
30
 
32
31
 
33
32
 
pyscipopt/iisfinder.pxi CHANGED
@@ -33,4 +33,5 @@ cdef SCIP_RETCODE PyiisfinderExec (SCIP_IIS* iis, SCIP_IISFINDER* iisfinder, SCI
33
33
  PyIIS.iis._iis = iis
34
34
  result_dict = PyIIS.iisfinderexec()
35
35
  assert isinstance(result_dict, dict), "iisfinderexec() must return a dictionary."
36
+ result[0] = result_dict.get("result", <SCIP_RESULT>result[0])
36
37
  return SCIP_OKAY