如何用Scipy解决含一维数组约束的线性优化问题?
加权和等式约束下的线性规划求解适配方案(针对scipy.optimize.linprog)
问题场景
需要求解带加权和等式约束的线性规划问题,约束形式为:weights @ x = constant
其中weights是一维权重数组,x是待优化的变量向量,constant是固定常数。
示例代码片段
# 目标函数:ones @ x -> min weights = np.array([...]) # 长度为n的一维权重数组 ones = np.ones_like(weights) coefficient = 1/2 * len(weights) * np.prod(weights) # 期望约束:weights @ x == coefficient
遇到的格式问题
scipy.optimize.linprog要求等式约束的系数矩阵A_eq必须是二维数组,但当前约束的系数是一维的weights- 不能将约束拆分为逐个
x_i的固定值约束,因为存在多组x满足加权和等于常数的情况,需要保留变量自由度
解决方案
1. 转换约束格式以适配linprog
直接将一维权重数组转为二维行矩阵,作为A_eq;将常数转为长度为1的一维数组作为b_eq,这完全符合linprog的要求,同时保留原约束的所有可行解空间。
完整示例代码:
import numpy as np from scipy.optimize import linprog # 示例权重数组 weights = np.array([2, 3, 4]) n = len(weights) # 目标函数系数 ones = np.ones_like(weights) # 约束右侧常数 coefficient = 1/2 * n * np.prod(weights) # 构造linprog要求的约束格式 A_eq = weights.reshape(1, -1) # 转为(1, n)的二维矩阵 b_eq = np.array([coefficient]) # 转为长度1的一维数组 # 调用linprog求解(可根据需求添加变量边界bounds) result = linprog(c=ones, A_eq=A_eq, b_eq=b_eq) print("优化结果:") print(result)
2. 约束有效性说明
这种转换完全等价于原约束:A_eq @ x的结果就是weights与x的加权和,等于b_eq中的常数。仅添加单个等式约束,不会限制单个x_i的取值,保留了所有满足加权和条件的可行解。
3. 多约束扩展
如果存在多个加权和等式约束,只需将每个一维权重数组作为一行添加到A_eq中,对应的常数依次添加到b_eq数组即可。例如两个约束时,A_eq形状为(2, n),b_eq为长度2的一维数组。
内容的提问来源于stack exchange,提问作者Nikita Artemenko
相关产品推荐
相关产品推荐

