You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为CVXPY优化问题的选择变量添加防频繁启停约束?

解决方案

问题分析

你当前的核心需求是避免容量选择出现0,1,0,1这类频繁启停的波动,对应的约束可以基于代表是否开启容量的selection[:,1]变量编写。另外你原代码存在一处小问题:原有代码中定义的cost_constraint是求和表达式,不是合法的等式/不等式约束,加入约束列表会导致报错,需要先移除。

约束实现

你提到的「某点位判定为1后,接下来2个点位必须为0」有两种常见的实现逻辑,按需选择即可:

方案1:严格禁止1之后的2个周期出现任何1(不允许连续开)

该方案完全禁止连续开启,也禁止间隔1个周期后再次开启,完全符合你描述的字面要求:

# 提取是否开启容量的标识:1代表开启,0代表关闭
on = selection[:, 1]
no_fluctuation_constraints = []
# 遍历所有可约束的位置(最后2个位置后无足够周期,无需约束)
for i in range(len(on) - 2):
    no_fluctuation_constraints.append(on[i] + on[i+1] + on[i+2] <= 1)

方案2:允许连续开启,仅禁止1,0,1式的启停波动

该方案匹配你给出的示例中允许[0,0,1,1,0,0]这类连续开启的场景,仅禁止开启1个周期就关闭、间隔1个周期又开启的频繁波动:

on = selection[:, 1]
no_fluctuation_constraints = []
for i in range(2, len(on)):
    # 禁止出现前前位为1、前位为0、当前位为1的1,0,1序列
    no_fluctuation_constraints.append(on[i-2] + on[i] <= 1 + on[i-1])

完整修改后的代码

把约束加入原有的约束列表即可,修改后完整代码如下(同时修复了原代码中变量名重复冲突的问题):

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_arr = 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)

# 基础约束
assignment_constraint = cp.sum(selection,axis=1) == 1
volume_= cp.sum(cp.multiply(ex,selection))
volume_constraint = volume_ >= v_min

# 防波动约束(方案1和方案2按需选择其一即可)
on = selection[:, 1]
no_fluctuation_constraints = []
# 方案1:严格禁止1之后2个周期出现1
# for i in range(len(on) - 2):
#     no_fluctuation_constraints.append(on[i] + on[i+1] + on[i+2] <= 1)
# 方案2:允许连续开,仅禁止1,0,1波动
for i in range(2, len(on)):
    no_fluctuation_constraints.append(on[i-2] + on[i] <= 1 + on[i-1])

# 合并所有约束
constraints = [assignment_constraint, volume_constraint] + no_fluctuation_constraints

# 目标函数
cost = cp.sum(cp.multiply(cost_arr, 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_arr,selection.value))
print(best_cost)
print(c)

内容的提问来源于stack exchange,提问作者Aidan Donnelly

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 10:24:03