1

I have CVXPY problem defined with a volume array, and a cost array to match each of volumes. The problem has 192 variables and 3 constraints which I have defined.

My goal is to minimize the cost in this problem to deliver a specific volume and avoid multiple periods where I get a 0, 1, 0, 1.

My current output could look something like follows:

[0, 0, 1, 1, 0, 1... 0, 1, 0, 1]

The ideal solution would avoid an amount. So if the selection decides a 1 at a point, the next 2 points should be 0. Such as below:

[0, 0, 1, 1, 0, 0... 0, 1, 0, 0]

I am unsure how to write such a constraint to include my selection with the problem I have currently programmed as can be seen here:

import cvxpy as cp
import numpy as np

# Volume and cost
full_cost = [[0, data] for data in [0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45,  0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45,0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45,  0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4]]
cost_ = np.array(full_cost)
ex = np.array([[0, 17100] for data in [i for i in range(0, 96)]])

# Minimum volume required
v_min = 300000

# Selection variable
selection = cp.Variable(shape=ex.shape, boolean=True)

# Constraints
assignment_constraint = cp.sum(selection,axis=1) == 1

volume_= cp.sum(cp.multiply(ex,selection))
volume_constraint = volume_ >= v_min

cost_constraint = cp.sum(cp.multiply(cost_, selection))

constraints = [assignment_constraint, volume_constraint, cost_constraint]

cost_ = cp.sum(cp.multiply(cost_,selection))

# Problem definition
assign_problem = cp.Problem(cp.Minimize(cost_), constraints)
assign_problem.solve(solver=cp.CPLEX, verbose=True)  

# Find solution in ex variable
assignments = [np.where(r==1)[0][0] for r in selection.value]
c = [ ex[i][assignments[i]] for i in range(len(assignments)) ]
best_volume = np.sum(np.multiply(ex,selection.value))
best_cost = np.sum(np.multiply(cost_,selection.value))
print(best_cost)
print(c)

I believe that the constraint should be based around my selection variable, but I am struggling to see how to include it as a constraint.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Aidan Donnelly
  • 369
  • 5
  • 19
  • What is it precisely that you want to exclude? The subsequence 0,1,0,1 ? The description is a little confusing since later you say "after 1 there should be two zeros" which means something else. – Michal Adamaszek Sep 29 '21 at 06:27
  • Hi, @MichalAdamaszek, sorry for this confusion. I wish to prevent patterns such that if a selection is 1, the next two selections subsequently be 0 or "Off". This would be to allow the pump to cooldown. Currently my output could look like ```0, 1, 0, 1``` which would be undesirable as this would be multiple start/stops (1,0). My ideal solution could look like ```0, 1, 1, 0``` or ```0, 1, 0, 0``` to ensure we do not harm the motor. – Aidan Donnelly Sep 29 '21 at 07:04

1 Answers1

1

If I understand correctly the it looks like you want to impose the condition

if   x[i]==1 and x[i+1]==0   then   x[i+2]==0

for binary variables x. That is equivalent to

x[i+2] <= 1 - x[i] + x[i+1]
  • 1
    Thanks for your answer. I have a few extra points I wish to ask. Would I define the binary variable like: ```x = cp.Variable()```? and how would I implement this into my selection variable which controls my output essentially. – Aidan Donnelly Sep 29 '21 at 07:40
  • 1
    I suppose it is the variable called ``selection`` that should play the role of ``x`` from my notation. – Michal Adamaszek Sep 29 '21 at 07:42
  • 2
    I have attempted to implement replace ```x``` with my variable ```selection``` as follows: ```selection[i+2] <= 1 - selection[i] + selection[i+1]```. Although the issue is now that I am returned ```IndexError: Index 97 is out of bounds for axis 0 with size 96.```. I am working with a fixed array size so I wonder if there is a work around for this. – Aidan Donnelly Sep 29 '21 at 07:44