如何限制您的问题以允许自定义 "cool-off period"?

How to constrict your problem to allow a custom-defined "cool-off period"?

我正在使用 CVXPY 和 CVXOPT 来解决一个问题,使我们能够以最便宜的方式控制 运行 电机。

我们有现有的约束,包括需要维护的成本、数量和级别(所有这些都有效,只是为了进一步定义手头的问题)。我们使用它来最小化成本并提供优化方法。

最近,我们希望添加一个允许冷静期的新约束。我们可以设置。因此,如果选择值为 1,那么接下来的两个周期应该为 0(如果这有意义的话)。本质上,如果泵运行了一段时间,它应该关闭以便接下来的两个时间冷却。

请参阅下面的当前正在使用的功能。目前,还没有实施冷却约束,并希望在如何最好地实施这种解决方案的正确方向上得到推动。

def optimiser(self, cost_, volume_,v_min,flow_,min_level,max_level,initial_level,period_lengths,out_flow_, errors) :
        """
        This function optimizes the regime possible combinations using convex optimization. We assign and define the problem and uses `GLPK_MI` to solve our problem.

        Parameters
        ----------
        cost_
            Numpy Array
        volume_
            Numpy Array
        v_min
            Float -> minimum volume
        flow_
            Numpy Array
        min_level
            Float -> minimum level
        max_level
            Float -> maximum level
        initial_level
            Float -> initial level
        period_lengths
            Integer -> number of period lengths
        out_flow_
            Numpy Array
        errors
            Exceptions -> error handling

        Returns
        ----------
        selection
            Solved problem with the best possible combination for pumping regime.
        """
        FACTOR =  0.001*1800*self.RESERVOIR_VOLUME
        input_flow_matrix=np.zeros((max(period_lengths),len(period_lengths)))
        for i,l in enumerate(period_lengths):
            input_flow_matrix[:l,i]=1
        selection = cp.Variable(shape=cost_.shape,boolean=True)
        assignment_constraint = cp.sum(selection,axis=1) == 1
        input_flow_= cp.sum(cp.multiply(flow_,selection),axis=1)
        input_flow_vector=cp.vec(cp.multiply(input_flow_matrix,np.ones((max(period_lengths), 1)) @ cp.reshape(input_flow_,(1,len(period_lengths)))))
        res_flow= (input_flow_vector-cp.vec(out_flow_))
        res_level=cp.cumsum(res_flow) * FACTOR + initial_level
        volume_= cp.sum(cp.multiply(volume_,selection))
        volume_constraint = volume_ >= v_min
        min_level_constraint = res_level >= min_level
        max_level_constraint = res_level <= max_level

        if errors is LevelTooLowError:
            constraints = [assignment_constraint, max_level_constraint, volume_constraint]
        elif errors is LevelTooHighError:
            constraints = [assignment_constraint, min_level_constraint, volume_constraint]
        elif errors is MaxVolumeExceededError:
            constraints = [assignment_constraint, min_level_constraint, volume_constraint]
        else:
            constraints = [assignment_constraint, max_level_constraint, min_level_constraint, volume_constraint]

        cost_ = cp.sum(cp.multiply(cost_,selection))
        assign_prob = cp.Problem(cp.Minimize(cost_),constraints)
        assign_prob.solve(solver=cp.GLPK_MI, verbose=False)   
        return selection

我们使用的数据样本

这是我们的cost_数组

[[0.   0.8 ]
 [0.   0.8 ]
 [0.   0.8 ]
 [0.   0.8 ]
 [0.   0.8 ]
 [0.   0.8 ]
 [0.   0.8 ]
 [0.   0.8 ]
 [0.   0.9 ]
 [0.   0.9 ]
 [0.   0.9 ]
 [0.   0.9 ]
 [0.   0.9 ]
 [0.   0.9 ]
 [0.   0.9 ]
 [0.   0.9 ]
 [0.   1.35]
 [0.   1.35]
 [0.   1.35]
 [0.   1.8 ]
 [0.   1.2 ]]

这是我们的 volume_ 数组

[[    0. 34200.]
 [    0. 34200.]
 [    0. 34200.]
 [    0. 34200.]
 [    0. 34200.]
 [    0. 34200.]
 [    0. 34200.]
 [    0. 34200.]
 [    0. 34200.]
 [    0. 34200.]
 [    0. 34200.]
 [    0. 34200.]
 [    0. 34200.]
 [    0. 34200.]
 [    0. 34200.]
 [    0. 34200.]
 [    0. 51300.]
 [    0. 51300.]
 [    0. 51300.]
 [    0. 68400.]
 [    0. 51300.]]

我希望我的问题已得到明确定义,以便任何人都能理解我现在想做什么。如果还有什么需要,我可以很乐意提供给大家。

提前致谢。

发电中有时会用到类似这样的东西。发电机可能必须先冷却,然后才能再次打开。

假设我们有一个 二进制变量 x[t] 指示发电机是否在时间段 t 即

 x[t] = 1 if machine is "on"
        0               "off"

那么我们要要求:

if x[t-1]=1 and x[t]=0 => x[t+1] = 0

这读作:如果在 t 关闭,则在 t+1 也保持关闭。这可以写成线性约束:

x[t+1] <= x[t] - x[t-1] + 1    for all periods t

如果我们读到“如果泵运行一段时间,它应该关闭以便接下来的两个时间冷却”,这表明另外,最大正常运行时间是1,那么我们可以简单的写:

x[t-1] + x[t] + x[t+1] <= 1  for all t

这将允许像 [0,0,0],[1,0,0],[0,1,0],[0,0,1] 这样的模式,但禁止像 [1,1,1],[0,1,1],[1,1,0],[1,0,1].

这样的模式