如何更改GUROBI模型中的常量并更新它?

2024-04-27 00:06:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在创建一个GUROBI-MILP(MIP)优化问题,这个问题需要用不同的常数项求解多次,无论是在目标函数中还是在线性约束中。你知道吗

该模型是针对不同的元素i进行模拟的,在24小时内,这意味着许多变量是以var_0[i,t] for i in [i1,i2,i3] for t in range(0,24)的形式存在的。我想为一年中的每个季节解决这个问题,因此必须执行4次运行,每个运行具有相同的模型结构,但常量的值不同。你知道吗

This question是类似的,但与之不同的是,我没有为每次运行更新一个RHS常量。This other看起来更像我的情况,但我并不真正理解接受的答案,也不知道如何在代码中实现它(因为obj。功能不变)。你知道吗

下面的示例完全是虚构的,但它代表了我在用代码做什么:

seasons = ("wi","sp","su","au")
def create_dictionaries(season=None):
# creates the dictionaries P1,P2,...,Pn taking the values from 
# a dataset and returns the dictionaries like this:
# P1 = {(i1,0) : 1, (i1,1) : 14, (i1,2) : -3, ...,
#       (i2,0) : 5, (i2,1) : -54, (i2,2) : -.5, ..., #and so on
#       ....}
# if season= None creates dummy dictionaries for the sake of
# not having an error while creating the model

class Model_custom():
    def __init__(self,nmodel="default"):
        self.m = Model(nmodel)

    def make_model(self):
        import constants as cstn #module that contains the values of constants a,b,c, ...
        modelname = "Model_"+season

        # Define the variables
        I = {i1,i2,i3}
        T = set(t for t in range(0,24))
        var_01 = self.m.addVars(I,T,vtype=GRB.CONTINUOUS,name='var_01',lb=0,ub=GRB.INFINITY)
        var_02 = self.m.addVars(I,T,vtype=GRB.CONTINUOUS,name='var_02',lb=0,ub=GRB.INFINITY)
        var_03 = self.m.addVars(I,T,vtype=GRB.CONTINUOUS,name='var_03',lb=0,ub=GRB.INFINITY)
        var_04 = self.m.addVars(I,T,vtype=GRB.CONTINUOUS,name='var_04',lb=0,ub=GRB.INFINITY)
        #more and more variables are made

        # Define the constraints
        self.m.addConstrs(cstn.a * var_01[i,t] - cnst.b * var_02[i,t] - C <=0 for i in I for t in T)
        ....
        # set objective function
        self.m.update()
        objective = (a * quicksum(P1[i,t] for t in T - b * var_04[i,t] for i in I for t in T) + k * quicksum(var_01[i,t]+ P2[u,t] * var_02[i,t] for i in I for t in T))
        self.m.setObjective(objective,GRB.MINIMIZE)

        def solve_model(self):
            try:
                self.m.optimize()
            except GurobiError as e:
                print('Error code '+ str(e.errno) + ": " + str(e))

            except AttributeError as err:
                print('Encountered an attribute error: ' + str(err))    

            if self.m.SolCount == 0:
                print("Model has no solution")
                exit(1)

test = Model_custom()
create_dictionaries()
test.make_model() 

for season in seasons:
    create_dictionaries(season) # creates the new set of constants
    test.m.update() # update the model
    test.solve_model() # solves the problem
    filename = season + "result.sol" 
    test.m.write(filename) # prints the result to file

此代码的预期行为是,在for循环中,创建一组新的常量,模型接收它们的更新值,解决问题并将结果打印到文件中。你知道吗

我观察到的检查结果是,模型没有按我期望的方式更新,其中常量的值保持不变。我发现的一个解决方法是:

for season in seasons:
    create_dictionaries(season) # creates the new set of constants
    test.make_model() # re-creates the model
    test.solve_model() # solves the problem
    filename = season + "result.sol" 
    test.m.write(filename) # prints the result to file

我不喜欢它,因为我认为它既不优雅,也没有计算效率(未来我计划在一年内解决同一个模型,这意味着8760小时,因此是一个更大更复杂的模型)。你知道吗

如何在现有模型中输入新的更新常量?你知道吗


Tags: thein模型testselfformodelvar