@@ -417,6 +417,11 @@ cdef class Column:
417
417
""" gets objective value coefficient of a column"""
418
418
return SCIPcolGetObj(self .scip_col)
419
419
420
+ def getAge (self ):
421
+ """ Gets the age of the column, i.e., the total number of successive times a column was in the LP
422
+ and was 0.0 in the solution"""
423
+ return SCIPcolGetAge(self .scip_col)
424
+
420
425
def __hash__ (self ):
421
426
return hash (< size_t> self .scip_col)
422
427
@@ -518,6 +523,10 @@ cdef class Row:
518
523
cdef SCIP_Real* vals = SCIProwGetVals(self .scip_row)
519
524
return [vals[i] for i in range (self .getNNonz())]
520
525
526
+ def getAge (self ):
527
+ """ Gets the age of the row. (The consecutive times the row has been non-active in the LP)"""
528
+ return SCIProwGetAge(self .scip_row)
529
+
521
530
def getNorm (self ):
522
531
""" gets Euclidean norm of row vector """
523
532
return SCIProwGetNorm(self .scip_row)
@@ -891,6 +900,10 @@ cdef class Variable(Expr):
891
900
""" Retrieve the current LP solution value of variable"""
892
901
return SCIPvarGetLPSol(self .scip_var)
893
902
903
+ def getAvgSol (self ):
904
+ """ Get the weighted average solution of variable in all feasible primal solutions found"""
905
+ return SCIPvarGetAvgSol(self .scip_var)
906
+
894
907
cdef class Constraint:
895
908
""" Base class holding a pointer to corresponding SCIP_CONS"""
896
909
@@ -1960,6 +1973,20 @@ cdef class Model:
1960
1973
""" returns whether the current LP solution is basic, i.e. is defined by a valid simplex basis"""
1961
1974
return SCIPisLPSolBasic(self ._scip)
1962
1975
1976
+ def allColsInLP (self ):
1977
+ """ checks if all columns, i.e. every variable with non-empty column is present in the LP.
1978
+ This is not True when performing pricing for instance."""
1979
+
1980
+ return SCIPallColsInLP(self ._scip)
1981
+
1982
+ # LP Col Methods
1983
+ def getColRedCost (self , Column col ):
1984
+ """ gets the reduced cost of the column in the current LP
1985
+
1986
+ :param Column col: the column of the LP for which the reduced cost will be retrieved
1987
+ """
1988
+ return SCIPgetColRedcost(self ._scip, col.scip_col)
1989
+
1963
1990
# TODO: documentation!!
1964
1991
# LP Row Methods
1965
1992
def createEmptyRowSepa (self , Sepa sepa , name = " row" , lhs = 0.0 , rhs = None , local = True , modifiable = False , removable = True ):
@@ -5553,6 +5580,119 @@ cdef class Model:
5553
5580
assert isinstance (var, Variable), " The given variable is not a pyvar, but %s " % var.__class__ .__name__
5554
5581
PY_SCIP_CALL(SCIPchgVarBranchPriority(self ._scip, var.scip_var, priority))
5555
5582
5583
+ def startStrongbranch (self ):
5584
+ """ Start strong branching. Needs to be called before any strong branching. Must also later end strong branching.
5585
+ TODO: Propagation option has currently been disabled via Python.
5586
+ If propagation is enabled then strong branching is not done on the LP, but on additionally created nodes (has some overhead)"""
5587
+
5588
+ PY_SCIP_CALL(SCIPstartStrongbranch(self ._scip, False ))
5589
+
5590
+ def endStrongbranch (self ):
5591
+ """ End strong branching. Needs to be called if startStrongBranching was called previously.
5592
+ Between these calls the user can access all strong branching functionality. """
5593
+
5594
+ PY_SCIP_CALL(SCIPendStrongbranch(self ._scip))
5595
+
5596
+ def getVarStrongbranchLast (self , Variable var ):
5597
+ """ Get the results of the last strong branching call on this variable (potentially was called
5598
+ at another node).
5599
+
5600
+ down - The dual bound of the LP after branching down on the variable
5601
+ up - The dual bound of the LP after branchign up on the variable
5602
+ downvalid - Whether down stores a valid dual bound or is NULL
5603
+ upvalid - Whether up stores a valid dual bound or is NULL
5604
+ solval - The solution value of the variable at the last strong branching call
5605
+ lpobjval - The LP objective value at the time of the last strong branching call
5606
+
5607
+ :param Variable var: variable to get the previous strong branching information from
5608
+ """
5609
+
5610
+ cdef SCIP_Real down
5611
+ cdef SCIP_Real up
5612
+ cdef SCIP_Real solval
5613
+ cdef SCIP_Real lpobjval
5614
+ cdef SCIP_Bool downvalid
5615
+ cdef SCIP_Bool upvalid
5616
+
5617
+ PY_SCIP_CALL(SCIPgetVarStrongbranchLast(self ._scip, var.scip_var, & down, & up, & downvalid, & upvalid, & solval, & lpobjval))
5618
+
5619
+ return down, up, downvalid, upvalid, solval, lpobjval
5620
+
5621
+ def getVarStrongbranchNode (self , Variable var ):
5622
+ """ Get the node number from the last time strong branching was called on the variable
5623
+
5624
+ :param Variable var: variable to get the previous strong branching node from
5625
+ """
5626
+
5627
+ cdef SCIP_Longint node_num
5628
+ node_num = SCIPgetVarStrongbranchNode(self ._scip, var.scip_var)
5629
+
5630
+ return node_num
5631
+
5632
+ def getVarStrongbranch (self , Variable var , itlim , idempotent = False , integral = False ):
5633
+ """ Strong branches and gets information on column variable.
5634
+
5635
+ :param Variable var: Variable to get strong branching information on
5636
+ :param itlim: LP iteration limit for total strong branching calls
5637
+ :param idempotent: Should SCIP's state remain the same after the call?
5638
+ :param integral: Boolean on whether the variable is currently integer.
5639
+ """
5640
+
5641
+ cdef SCIP_Real down
5642
+ cdef SCIP_Real up
5643
+ cdef SCIP_Bool downvalid
5644
+ cdef SCIP_Bool upvalid
5645
+ cdef SCIP_Bool downinf
5646
+ cdef SCIP_Bool upinf
5647
+ cdef SCIP_Bool downconflict
5648
+ cdef SCIP_Bool upconflict
5649
+ cdef SCIP_Bool lperror
5650
+
5651
+ if integral:
5652
+ PY_SCIP_CALL(SCIPgetVarStrongbranchInt(self ._scip, var.scip_var, itlim, idempotent, & down, & up, & downvalid,
5653
+ & upvalid, & downinf, & upinf, & downconflict, & upconflict, & lperror))
5654
+ else :
5655
+ PY_SCIP_CALL(SCIPgetVarStrongbranchFrac(self ._scip, var.scip_var, itlim, idempotent, & down, & up, & downvalid,
5656
+ & upvalid, & downinf, & upinf, & downconflict, & upconflict, & lperror))
5657
+
5658
+ return down, up, downvalid, upvalid, downinf, upinf, downconflict, upconflict, lperror
5659
+
5660
+ def updateVarPseudocost (self , Variable var , valdelta , objdelta , weight ):
5661
+ """ Updates the pseudo costs of the given variable and the global pseudo costs after a change of valdelta
5662
+ in the variable's solution value and resulting change of objdelta in the LP's objective value.
5663
+ Update is ignored if objdelts is infinite. Weight is in range (0, 1], and affects how it updates
5664
+ the global weighted sum.
5665
+
5666
+ :param Variable var: Variable whos pseudo cost will be updated
5667
+ :param valdelta: The change in variable value (e.g. the fractional amount removed or added by branching)
5668
+ :param objdelta: The change in objective value of the LP after valdelta change of the variable
5669
+ :param weight: the weight in range (0,1] of how the update affects the stored weighted sum.
5670
+ """
5671
+
5672
+ PY_SCIP_CALL(SCIPupdateVarPseudocost(self ._scip, var.scip_var, valdelta, objdelta, weight))
5673
+
5674
+ def getBranchScoreMultiple (self , Variable var , gains ):
5675
+ """ Calculates the branching score out of the gain predictions for a branching with
5676
+ arbitrary many children.
5677
+
5678
+ :param Variable var: variable to calculate the score for
5679
+ :param gains: list of gains for each child.
5680
+ """
5681
+
5682
+ assert isinstance (gains, list )
5683
+ nchildren = len (gains)
5684
+
5685
+ cdef int _nchildren = nchildren
5686
+ _gains = < SCIP_Real* > malloc(_nchildren * sizeof(SCIP_Real))
5687
+ for i in range (_nchildren):
5688
+ _gains[i] = gains[i]
5689
+
5690
+ score = SCIPgetBranchScoreMultiple(self ._scip, var.scip_var, _nchildren, _gains)
5691
+
5692
+ free(_gains)
5693
+
5694
+ return score
5695
+
5556
5696
def getTreesizeEstimation (self ):
5557
5697
""" Get an estimation of the final tree size """
5558
5698
return SCIPgetTreesizeEstimation(self ._scip)
@@ -5697,7 +5837,7 @@ class Statistics:
5697
5837
@property
5698
5838
def n_presolved_maximal_cons (self ):
5699
5839
return self ._presolved_constraints[" maximal" ]
5700
-
5840
+
5701
5841
# debugging memory management
5702
5842
def is_memory_freed ():
5703
5843
return BMSgetMemoryUsed() == 0
0 commit comments