scipy最小化SLSQP-'LSQ子问题中的奇异矩阵C' [英] scipy minimize SLSQP - 'Singular matrix C in LSQ subproblem'
问题描述
我正在尝试使用SciPy解决一个非常基本的优化问题.这个问题是受约束的,并且范围是可变的,我很确定它是线性的.
I'm trying to solve a pretty basic optimization problem using SciPy. The problem is constrained and with variable bounds and I'm pretty sure it's linear.
当我运行以下代码时,执行失败,并显示错误消息"LSQ子问题中的奇异矩阵C".有谁知道可能是什么问题?预先感谢.
When I run the following code the execution fails with the error message 'Singular matrix C in LSQ subproblem'. Does anyone know what the problem might be? Thanks in advance.
我将在此处添加简短的代码说明. 我在代码的开头定义了一个需求"向量.该向量描述了在一段时间内建立索引的特定产品的需求.我想弄清楚的是如何下订单,以便在某些约束下满足这一需求.这些约束是;
I'll add a short description of what the code should do here. I define a 'demand' vector at the beginning of the code. This vector describes the demand of a certain product indexed over some period of time. What I want to figure out is how to place a set of orders so as to fill this demand under some constraints. These constraints are;
- 如果在特定时间点有需求(需求指数),我们必须有库存商品
- 在下订单后的4个时间单位"之前,我们无法下订单
- 我们不能以最近4个时间单位下订单
这是我的代码;
from scipy.optimize import minimize
import numpy as np
demand = np.array([5, 10, 10, 7, 3, 7, 1, 0, 0, 0, 8])
orders = np.array([0.] * len(demand))
def objective(orders):
return np.sum(orders)
def items_in_stock(orders):
stock = 0
for i in range(len(orders)):
stock += orders[i]
stock -= demand[i]
if stock < 0.:
return -1.
return 0.
def four_weeks_order_distance(orders):
for i in range(len(orders)):
if orders[i] != 0.:
num_orders = (orders[i+1:i+5] != 0.).any()
if num_orders:
return -1.
return 0.
def four_weeks_from_end(orders):
if orders[-4:].any():
return -1.
else:
return 0.
con1 = {'type': 'eq', 'fun': items_in_stock}
con2 = {'type': 'eq', 'fun': four_weeks_order_distance}
con3 = {'type': 'eq', 'fun': four_weeks_from_end}
cons = [con1, con2, con3]
b = [(0, 100)]
bnds = b * len(orders)
x0 = orders
x0[0] = 10.
minimize(objective, x0, method='SLSQP', bounds=bnds, constraints=cons)
推荐答案
尽管我不是运筹学研究员,但我相信这是因为您实施的约束不是连续的.我做了很少的更改,以使约束现在本质上是连续的.
Though I am not an Operational Researcher, I believe it is because of the fact that the constraints you implemented are not continuous. I made little changes so that the constraints are now continuous in nature.
from scipy.optimize import minimize
import numpy as np
demand = np.array([5, 10, 10, 7, 3, 7, 1, 0, 0, 0, 8])
orders = np.array([0.] * len(demand))
def objective(orders):
return np.sum(orders)
def items_in_stock(orders):
"""In-equality Constraint: Idea is to keep the balance of stock and demand.
Cumulated stock should be greater than demand. Also, demand should never cross the stock.
"""
stock = 0
stock_penalty = 0
for i in range(len(orders)):
stock += orders[i]
stock -= demand[i]
if stock < 0:
stock_penalty -= abs(stock)
return stock_penalty
def four_weeks_order_distance(orders):
"""Equality Constraint: An order can't be placed until four weeks after any other order.
"""
violation_count = 0
for i in range(len(orders) - 6):
if orders[i] != 0.:
num_orders = orders[i + 1: i + 5].sum()
violation_count -= num_orders
return violation_count
def four_weeks_from_end(orders):
"""Equality Constraint: No orders in the last 4 weeks
"""
return orders[-4:].sum()
con1 = {'type': 'ineq', 'fun': items_in_stock} # Forces value to be greater than zero.
con2 = {'type': 'eq', 'fun': four_weeks_order_distance} # Forces value to be zero.
con3 = {'type': 'eq', 'fun': four_weeks_from_end} # Forces value to be zero.
cons = [con1, con2, con3]
b = [(0, 100)]
bnds = b * len(orders)
x0 = orders
x0[0] = 10.
res = minimize(objective, x0, method='SLSQP', bounds=bnds, constraints=cons,
options={'eps': 1})
结果
status: 0
success: True
njev: 22
nfev: 370
fun: 51.000002688311334
x: array([ 5.10000027e+01, 1.81989405e-15, -6.66999371e-16,
1.70908182e-18, 2.03187432e-16, 1.19349893e-16,
1.25059614e-16, 4.55582386e-17, 6.60988392e-18,
3.37907550e-17, -5.72760251e-18])
message: 'Optimization terminated successfully.'
jac: array([ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 0.])
nit: 23
[ round(l, 2) for l in res.x ]
[51.0, 0.0, -0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.0]
因此,该解决方案建议在第一周下达所有订单.
So, the solution suggests to make all the orders in the first week.
- 它避免了缺货的情况
- 单一购买(订单)会在下订单后的四周内遵守无订单.
- 最近4周没有购买
这篇关于scipy最小化SLSQP-'LSQ子问题中的奇异矩阵C'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!