如何将 class 实例的变量存储在另一个 class 实例中
How to store a variable of an instance of a class in an instance of another class
我有两个自定义的 classes,一个是 gurobipy-class 的子项,应该制作一个 lp 模型。我制作的另一个用于存储变量。现在我想在变量class中存储模型class的一些变量。
这是我的 classes:
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())
这是我要存储的 x 变量。首先,我尝试将其存储在 Model-class 的实例中。我在 init 函数中添加了这一行 self.x = None
。但它引发了 AttributeError: 'x' is not a model attribute
。我想,这是因为 gurobipy-class 没有 x 属性。
接下来,我想把它存储在变量的一个实例中-class。我想在模型 class 中编写一个函数,这应该可以解决问题。这是函数:
def store_x(self, var):
var.x = self.x
然后,我得到这个错误:gurobipy.GurobiError: Unable to retrieve attribute 'x'
,我不明白为什么。
我什至无法从函数外部访问 x 变量。我可以从函数内部打印它,但仅此而已。问题是,我在后期需要这个 x 变量。
我怎样才能做到这一点?我如何存储 x 变量以便稍后访问它?它不必在变量-class 中,也欢迎任何其他解决方案。
好的,首先我发现您的代码有问题:
def store_x(self, var):
var.x = self.x
需要改为:
def store_x(self, var):
self.x = var.x
这是因为无论您在 'var' 参数中发送什么,都只会是您实际传递的任何内容的副本。然后它的范围只会持续到 store_x 方法的末尾。因此,您传递该副本并告诉您的变量 class 实例将其存储在它的 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'、'Model':
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)
我有两个自定义的 classes,一个是 gurobipy-class 的子项,应该制作一个 lp 模型。我制作的另一个用于存储变量。现在我想在变量class中存储模型class的一些变量。 这是我的 classes:
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())
这是我要存储的 x 变量。首先,我尝试将其存储在 Model-class 的实例中。我在 init 函数中添加了这一行 self.x = None
。但它引发了 AttributeError: 'x' is not a model attribute
。我想,这是因为 gurobipy-class 没有 x 属性。
接下来,我想把它存储在变量的一个实例中-class。我想在模型 class 中编写一个函数,这应该可以解决问题。这是函数:
def store_x(self, var):
var.x = self.x
然后,我得到这个错误:gurobipy.GurobiError: Unable to retrieve attribute 'x'
,我不明白为什么。
我什至无法从函数外部访问 x 变量。我可以从函数内部打印它,但仅此而已。问题是,我在后期需要这个 x 变量。
我怎样才能做到这一点?我如何存储 x 变量以便稍后访问它?它不必在变量-class 中,也欢迎任何其他解决方案。
好的,首先我发现您的代码有问题:
def store_x(self, var):
var.x = self.x
需要改为:
def store_x(self, var):
self.x = var.x
这是因为无论您在 'var' 参数中发送什么,都只会是您实际传递的任何内容的副本。然后它的范围只会持续到 store_x 方法的末尾。因此,您传递该副本并告诉您的变量 class 实例将其存储在它的 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'、'Model':
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)