如何更改GUROBI模型中的常数并进行更新?

时间:2019-08-28 10:31:00

标签: python gurobi

我正在创建一个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

我不喜欢它,因为我认为它既不优雅也不计算效率高(将来我计划在1年内求解相同的模型,这意味着需要8760小时,因此是一个更大,更复杂的模型)。 / p>

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

0 个答案:

没有答案