Как сохранить переменную экземпляра класса в экземпляре другого класса - PullRequest
0 голосов
/ 28 марта 2019

У меня есть два самоопределяемых класса, один из которых является дочерним классом gurobipy и должен создать lp-модель.Другой я сделал для хранения переменных.Теперь я хочу сохранить некоторые переменные класса модели в классе переменных.Вот мои классы:

class Model(gb.Model):
    def __init__(self):
        super().__init__()

    def create_model(self, var):
        dim = var.dimensions()
        # variables
        x = self.addVars(dim[0], dim[1], vtype=gb.GRB.BINARY, name="x")
        D_l = self.addVars(dim[1], lb=0, name='D_l')
        D_max = self.addVar(lb=0, name='D_max')
        # objective
        self.setObjective(D_max, gb.GRB.MINIMIZE)
        # constraints
        self.addConstrs((x.sum(i, '*') == 1 for i in range(dim[0])), name="b")
        self.addConstrs((D_max >= D_l[l] for l in range(dim[1])), name="c")
        self.addConstrs((D_l[l] >= var.dist_mat()[i, j] * (x[i, l] + x[j, l] - 1) for i in range(dim[0])
                          for j in range(dim[0]) for l in range(dim[1])), name='a')
        self.update()


class Variables:
    def __init__(self, data, number_of_clusters, neighbourhood_size):
        self.data = data
        self.number_of_clusters = number_of_clusters
        self.neighbourhood_size = neighbourhood_size
        self.variables_before = None
        self.variables_now = None
        self.ofv_before = None
        self.ofv_now = None
        self.x = None

    def dist_mat(self):
        from scipy.spatial import distance_matrix
        return distance_matrix(self.data, self.data)

    def dimensions(self):
        from numpy import shape
        data_objects = shape(self.data)[0]
        number_of_clusters = self.number_of_clusters
        return data_objects, number_of_clusters

    def print_dist_mat(self):
        print(self.dist_mat())

Это х-переменная, которую я хочу сохранить.Сначала я попытался сохранить его в экземпляре класса Model.Я добавил в init -функцию эту строку self.x = None.Но это поднимает AttributeError: 'x' is not a model attribute.Я полагаю, это потому, что у класса gurobipy нет атрибута ax.

Далее я хотел сохранить его в экземпляре класса переменных.Я хотел написать функцию в классе модели, которая должна сделать свое дело.Это функция:

def store_x(self, var):
    var.x = self.x

Затем я получил эту ошибку: gurobipy.GurobiError: Unable to retrieve attribute 'x', я не могу понять, почему.

Я даже не могу получить доступ к переменной x извне функции.Я могу напечатать это изнутри функции, но не более того.Проблема в том, что мне нужна эта x-переменная на более поздней стадии.

Как мне этого добиться?Как я могу сохранить переменную x, чтобы получить к ней доступ позже?Это не обязательно должно быть в классе переменных, также приветствуется любое другое решение.

1 Ответ

0 голосов
/ 28 марта 2019

Хорошо, во-первых, я вижу проблему с вашим кодом:

def store_x(self, var):
    var.x = self.x

Необходимо изменить на:

def store_x(self, var):
    self.x = var.x

Это потому, что все, что вы отправляете в параметре 'var', будет только копией того, что вы действительно передали. И тогда его область действия будет длиться только до конца этого метода store_x. Таким образом, вместо этого вы передаете эту копию и говорите своему экземпляру класса переменной сохранить его внутри значения x.

Что касается полученной вами ошибки:

self.x = None # inside your Model class

Я не уверен почему, так как я попробовал следующее, и все работает нормально:

class Variables:
    def __init__(self):
        self.data = data
        self.number_of_clusters = number_of_clusters
        self.neighbourhood_size = neighbourhood_size
        self.variables_before = None
        self.variables_now = None
        self.ofv_before = None
        self.ofv_now = None
        self.x = None

Так что я обновляю свой ответ более глубоким примером после получения разъяснений о том, что необходимо. Вот два каркасных класса с именами «Переменные», «Модель», соответственно:

class Variables:
    def __init__(self):
        self.data = None
        self.number_of_clusters = None
        self.neighbourhood_size = None
        self.variables_before = None
        self.variables_now = None
        self.ofv_before = None
        self.ofv_now = None
        self.x = None


    def get_x(self,modelx):

        self.x = modelx


class Model:
    def __init__(self):
        self.x = ({}, {})



# create your class instances here

newVar = Variables()
newModel = Model()

# one way to assign your Variable class's x attribute the tuple dict in question.  
newVar.x = newModel.x 

# alternate way is to create a function inside your Variable class that updates the x variable based on the argument you send it.  
newVar.get_x(newModel.x)
...