【问题标题】:Scipy minimize: how to restrict x only to 0 and 1?Scipy 最小化:如何将 x 限制为 0 和 1?
【发布时间】:2016-06-16 07:44:07
【问题描述】:

我想用 Scipy.optimize.minimize 最小化具有多个参数和约束的函数:

def f(x):
    return -1*(0.9*x[0] + 0.8*x[1] + 0.85*x[2])*(0.95*x[3] + 0.8*x[4] + 0.7*x[5])*(0.98*x[6] + 0.94*x[7])

x0 = [0, 0, 1, 0, 0, 1, 0, 1]

cons=({'type': 'eq',
   'fun': lambda x: x[0] + x[1] + x[2] - 1},
  {'type': 'eq',
   'fun': lambda x: x[3] + x[4] + x[5] - 1},
  {'type': 'eq',
   'fun': lambda x: x[6] + x[7] - 1},
  {'type': 'ineq',
   'fun': lambda x: -1*(3*x[0] + x[1] + 2*x[2] + 3*x[3] + 2*x[4] + x[5] + 3*x[6] + 2*x[7] - 6)})

如何告诉python x[i] 只能是0和1?

【问题讨论】:

标签: python optimization scipy mathematical-optimization


【解决方案1】:

理论上你可以添加等式约束:

x[i] * (x[i]-1) = 0

在实践中,这并不能很好地工作,因为这给模型增加了令人讨厌的非凸性。它看起来你有一个非线性目标和线性约束和二进制变量,所以这表明我们需要查看一个 MINLP(混合整数非线性规划)求解器。这样的求解器很容易获得(例如BonminCouenneBaronAntigone)。

但是我们可以做一些事情。我们可以扩展您的目标,并编写

maximize 0.9*0.95*0.98*x[0]*x[3]*x[6] + 0.9*0.95*0.94*x[0]*x[3]*x[7] + ...

maximize c1*(x[0]*x[3]*x[6]) + c2*(x[0]*x[3]*x[7]) + ...

x[0]*x[3]*x[6] 这样的产品,其中所有 x[i] 都是 0-1 或二进制变量,可以如下线性化:

maximize c1*y1 + c2*y2 + ....
y1 <= x[0]
y1 <= x[3]
y1 <= x[6]
y2 <= x[0]
y2 <= x[3]
y2 <= x[7]
...
y1,y2,... binary variables

如果我们愿意,我们可以将y1,y2,... 设为介于 0 和 1 之间的连续变量。它们将自动为零或一。更多详情请联系here

我们现在拥有的是线性目标和线性约束以及二元变量x[i], y[j]。这可以使用现成的 MIP(混合整数规划)求解器来解决。非常好的是CplexGurobi,但也有公共领域的CBCGLPK。其中许多都有 Python 绑定。

【讨论】:

    猜你喜欢
    • 2019-10-01
    • 2018-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多