1

Problem

I'm using PySCIPOpt to implement a branch and price algorithm in SCIP. I would like to add additional attributes to pyscipopt.scip.Variable objects (this is the class that PySCIPOpt uses to handle model variables) in order to store additional information on the variables.

However, doing this in the classical Python-way of adding an attribute to an object, gives me an AttributeError.

My suspicion - without really understanding what's going on - is that while this is possible with a "classical" python class, the Variable objects are created by the underlying Cython code of PySCIPOpt and therefore, dynamically adding attributes is somehow not supported.

For the column generation part of my Branch and Price code, I need to somehow store, whenever a new variable is created by the Pricer, what type of solution component my variable represents (e.g. for a Cutting Stock implementation, that would be the cutting pattern the variable corresponds to). I believe storing additional information on the variables by adding an attribute would - if it worked - be the most elegant way to accomplish this.

Here's an MWE:

from pyscipopt import Model

s = Model()

new_var = s.addVar(vtype="C", obj = 5)
new_var.foo = {'bar': 'baz'} # some arbitrary information about new_var I want to store

which returns

AttributeError: 'pyscipopt.scip.Variable' object has no attribute 'foo'

instead of adding an attribute named foo.

Question

  • Is there any way of dynamically adding attributes to variables?
  • Is there a different/better way of storing information on the variables so that it can be accessed throughout my entire SCIP routine (e.g., it should also be accessable by the Pricers and Branchrules)?
netword
  • 113
  • 2
  • 13
  • 1
    I know nothing about PySCIPOpt, but if you inherit from a Cython class you should be able to add attributes to instances of the inherited class – DavidW Mar 25 '19 at 19:43
  • Yes, this should also work, but adding a placeholder object to the Cython class itself is more user-friendly. – mattmilten Mar 26 '19 at 07:26

1 Answers1

1

As far as I know this is not possible in a dynamic way. For some classes (Model, Constraint, ...), though, there are blank object placeholders that can take any Python data:

cdef class Constraint:
    cdef SCIP_CONS* scip_cons
    cdef public object data

I suppose these should exist for all classes. See here: https://github.com/SCIP-Interfaces/PySCIPOpt/issues/268

mattmilten
  • 6,242
  • 3
  • 35
  • 65
  • This sounds good; indeed, for `Model` it works - however, not yet for `Variable`. For clarification: when you say *these should exist for all classes*, do you mean that in the sense of *they currently don't, but it would be good if they existed* or as in *I think they exist for all classes* ? – netword Mar 25 '19 at 17:17
  • 1
    What I meant was: They do not yet exist, but they really should :-) You are welcome to create a pull request over on GitHub. – mattmilten Mar 25 '19 at 17:20