scipy.optimize.linprog的A_eq维度与Bounds参数支持问题咨询
问题1:linprog要求A_eq为二维数组的解决方法
scipy.optimize.linprog的A_eq参数明确要求传入二维数组,行对应约束数量,列对应决策变量数量,哪怕只有1个等式约束也需要显式构造为二维结构,否则就会触发维度不匹配报错。
你使用的添加全零约束的临时方案虽然数学上等价,但属于冗余操作,通用的正确处理方式如下:
- 单个等式约束场景:给一维数组增加一个维度即可,可通过
reshape方法实现,修改后的可运行代码如下:
import numpy from scipy import optimize c = [0.056,0.0001,0.2099,0.1429,0.0682] # 把一维的Aeq转为shape为(1, 变量数)的二维数组 Aeq = numpy.ones(len(c)).reshape(1, -1) beq = 1 bounds = [(0, 0.4), (0, 0.4), (0, 0.4), (0, 0.4), (0, 0.4)] res = optimize.linprog(c, A_eq=Aeq, b_eq=beq, bounds=bounds)
- 3个或多个等式约束场景:直接构造二维数组即可,每一行对应一个约束,天然符合二维格式要求,不需要额外处理,示例如下:
# 3个约束、5个变量的A_eq示例,shape为(3,5) Aeq = numpy.array([ [1,1,1,1,1], # 约束1:sum(x) = 1 [1,0,2,0,1], # 约束2:自定义规则 [0,3,0,1,0] # 约束3:自定义规则 ]) beq = [1, 0.6, 0.3]
问题2:linprog不支持optimize.Bounds类型的原因和解决方案
optimize.Bounds是scipy后期为通用非线性优化接口minimize设计的参数类型,而linprog作为更早推出的专用线性规划接口,初始设计时就只支持(下限, 上限)元组组成的列表作为边界入参,目前官方没有对该接口做Bounds类型的兼容适配,因此直接传入会触发类型错误。
如果已经生成了Bounds对象,可以手动转换为linprog支持的格式,转换代码如下:
bounds_obj = optimize.Bounds([0,0,0,0,0],[0.4,0.4,0.4,0.4,0.4]) # 转为linprog支持的元组列表格式 bounds = list(zip(bounds_obj.lb, bounds_obj.ub)) # 后续直接传入linprog即可 res = optimize.linprog(c, A_eq=Aeq, b_eq=beq, bounds=bounds)
内容的提问来源于stack exchange,提问作者Bastian Löffler
相关产品推荐
相关产品推荐

