Reputation: 389
I have a convex optimisation problem with many different constraints that ensure level, running times etc. In this case assume N is 8.
See my problem written below:
N = len(periods_minutes)
MIN_RUN_TIME = 25
running_time = cp.Variable(N, integer=True)
k = cp.Variable(N)
mins = np.ones(N) * MIN_RUN_TIME
maxs = np.ones(N) * periods_minutes
print(mins)
# Constant variables
pump_flow = float(self.pump_data[len(self.pump_data)-1]["Flow"])
pump_energy = float(self.pump_data[len(self.pump_data)-1]["Energy"])
pump_flow_per_minute = pump_flow * 60
# Optimiation calculations
cost_of_running = cp.multiply((running_time/60), energy_costs * pump_energy)
sum_of_energy = cp.sum(cost_of_running)
volume_cp = cp.sum(running_time*pump_flow_per_minute)
period_volume = running_time * pump_flow_per_minute
# Reservoir information and calculations
FACTOR = 1/self.SURFACE_AREA
flow_in = running_time * pump_flow_per_minute
flow_diff = (flow_in - flow_out) / 1000
res_level = cp.cumsum(flow_diff) * FACTOR + self.current_level
# Constant constraints
min_level_constraint = res_level >= self.min_level
max_level_constraint = res_level <= self.max_level
volume_constraint = volume_cp >= self.target
# running_time_constraint = 0 == running_time >= 20
# Build constraints
constraints = []
for i in range(N):
constraints += [running_time[i] >= 0]
constraints += [running_time[i] >= cp.multiply(k[i], mins)]
constraints += [running_time[i] <= cp.multiply(k[i], maxs)]
# Append common constraints
constraints += [min_level_constraint]
constraints += [max_level_constraint]
constraints += [volume_constraint]
# constraints += [running_time_constraint]
# Objective definition
objective = cp.Minimize(cp.sum(sum_of_energy))
# Problem declaration
prob = cp.Problem(objective, constraints)
prob.solve(solver=cp.CPLEX, verbose=False)
I want to write a conditional statement like follows as a constraint:
if running_time[i] > 0:
# Then it needs to be greater than a set value/variable
running_time[i] >= Y || 20
I essentially need a minimum run time if we decide in the problem that running_time[i] is something like 4 or below 20, but we can allow it to be 0 if I have explained that correctly.
I have updated the question based on another answer and comments made below.
Upvotes: 0
Views: 1017
Reputation: 389
Update: Thanks for everyone's comments and suggestions for the Cookbook and other Stack Overflow question I was able to implement the required constraints to satisfy my problem. See below for my updated code.
N = len(periods_minutes)
MIN_RUN_TIME = 20
running_time = cp.Variable(N, integer=True)
mins = np.ones(N) * MIN_RUN_TIME
maxs = np.ones(N) * periods_minutes
k = cp.Variable(N, boolean=True)
# Constant variables
pump_flow = float(self.pump_data[len(self.pump_data)-1]["Flow"])
pump_energy = float(self.pump_data[len(self.pump_data)-1]["Energy"])
pump_flow_per_minute = pump_flow * 60
# Optimiation calculations
running_time_hours = running_time / 60
cost_of_running = cp.multiply(running_time_hours, energy_costs) * pump_energy
sum_of_energy = cp.sum(cost_of_running)
volume_cp = cp.sum(running_time*pump_flow_per_minute)
period_volume = running_time * pump_flow_per_minute
# Reservoir information and calculations
FACTOR = 1/self.SURFACE_AREA
flow_in = running_time * pump_flow_per_minute
flow_diff = (flow_in - flow_out) / 1000
res_level = cp.cumsum(flow_diff) * FACTOR + self.current_level
# Constant constraints
min_level_constraint = res_level >= self.min_level
max_level_constraint = res_level <= self.max_level
volume_constraint = volume_cp >= self.target
# Build constraints
constraints = []
# Append common constraints
constraints += [min_level_constraint]
constraints += [max_level_constraint]
constraints += [volume_constraint]
constraints += [running_time >= cp.multiply(k, mins)]
constraints += [running_time <= cp.multiply(k, maxs)]
# Objective definition
objective = cp.Minimize(cp.sum(sum_of_energy))
# Problem declaration
prob = cp.Problem(objective, constraints)
prob.solve(solver=cp.CPLEX, verbose=False)
Upvotes: 1