Scipy最小化:如何将x限制为0和1?

Scipy minimize: how to restrict x only to 0 and 1?(Scipy最小化:如何将x限制为0和1?)
本文介绍了Scipy最小化:如何将x限制为0和1?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要使用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?

推荐答案

理论上您可以添加相等约束:

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

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

然而,我们可以做一些事情。我们可以扩展您的目标,然后写下

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之间连续。它们将自动为0或1。更多详细信息请参阅here。

我们现在得到的是线性目标、线性约束和二元变量x[i], y[j]。这可以用现成的MIP(混合整数规划)解算器来解决。非常好的是Cplex和Gurobi,但也有公共领域的CBC和GLPK。它们中的许多都有Python绑定。

这篇关于Scipy最小化:如何将x限制为0和1?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Leetcode 234: Palindrome LinkedList(Leetcode 234:回文链接列表)
How do I read an Excel file directly from Dropbox#39;s API using pandas.read_excel()?(如何使用PANDAS.READ_EXCEL()直接从Dropbox的API读取Excel文件?)
subprocess.Popen tries to write to nonexistent pipe(子进程。打开尝试写入不存在的管道)
I want to realize Popen-code from Windows to Linux:(我想实现从Windows到Linux的POpen-code:)
Reading stdout from a subprocess in real time(实时读取子进程中的标准输出)
How to call type safely on a random file in Python?(如何在Python中安全地调用随机文件上的类型?)