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

  cvxpy, mathematical-optimization, python

I am making use of CVXPY and CVXOPT to solve a problem which allows us to control the running of motors in the cheapest possible ways.

We have existing constraints which consist of, cost, volume and level which needs to be maintained (all of which work, and is only to give a further definition of the problem at hand). We use this to minimize the cost and provide an optimized approach.

Recently, we wish to add a new constraint which will allow for a cool-off period. Which we can set. So if the selection value is 1, the next two periods should be a 0 if this makes sense. Essentially, if the pump runs for a period it should be off for the next two to cool down.

Please see below for a current function which is being used. Currently no cool-off constraint has been implemented and wish to get a push in the right direction of how best to implement such a solution.

def optimiser(self, cost_, volume_,v_min,flow_,min_level,max_level,initial_level,period_lengths,out_flow_, errors) :
        """
        This function optimises the regime possible combinations using convex optimisation. 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

I hope my problem has been well defined for anyone to understand what I wish to do at the moment. If anything else is needed, I can happily provide this for anyone.

Thanks in advance.

Source: Python Questions

LEAVE A COMMENT