Python 求具有边界和约束的离散变量的函数最小值

Python 求具有边界和约束的离散变量的函数最小值,python,scipy-optimize,mystic,discrete-optimization,Python,Scipy Optimize,Mystic,Discrete Optimization,我试图找到一种(相对)快速的方法来最小化给定约束和边界的自然数集合上的函数。我知道函数的数学形式及其约束条件,所以蛮力方法似乎很慢,也不是很优雅。解决这个问题最好的办法是什么 基本上,我试图使用scipy.optimize.minimize将实数的函数最小化推广到自然数的函数最小化。(我知道这要困难得多) 使事情变得容易。我在想这样的事情 例如: 从scipy导入优化 x0=[0,0] cons=({'type':'ineq','fun':lambda x:0.4-x[1]}) 界限=((0,无

我试图找到一种(相对)快速的方法来最小化给定约束和边界的自然数集合上的函数。我知道函数的数学形式及其约束条件,所以蛮力方法似乎很慢,也不是很优雅。解决这个问题最好的办法是什么

基本上,我试图使用scipy.optimize.minimize将实数的函数最小化推广到自然数的函数最小化。(我知道这要困难得多)

使事情变得容易。我在想这样的事情 例如:

从scipy导入优化
x0=[0,0]
cons=({'type':'ineq','fun':lambda x:0.4-x[1]})
界限=((0,无),(0,无))
fun=λx:(x[0]-1.5)**2+(x[1]-0.5)**2+3
res=optimize.minimize(有趣,x0=x0,bounds=bounds,constraints=cons)
打印(res)
换言之,我希望在

fun=lambda x:(x[0]-1.5)**2+(x[1]-0.5)**2+3
xr=[(0,0)、(0,1)、(0,2)、(0,3)、(1,0)、(1,1)、(1,2)、(1,3)、(2,0)、(2,1)、(2,2)、(2,3)、(3,0)、(3,1)、(3,2)、(3,3),]
min_idx=min(xr,key=fun)
最小值=乐趣(最小值)
打印(最小值、最小值)
(我知道我可以通过从xr中排除这些值来强制执行它们,但这对于我心目中的实际情况来说似乎不太优雅,也不太实用)


所以我希望会有一些不同的迷你们像scipy.optimize.basinhopping或者神秘主义者的东西来做这个把戏?有什么建议吗?

我稍微修改了你的问题,让它变得更难一点

  Minimize:
            f(x) = (x0 - 1.5)**2 + (x1 - 0.5)**2 + 3

  Where: 
            0 =< x0
            0 =< x1 < 4.1 - x0
            x0,x1 are integers
最小化:
f(x)=(x0-1.5)**2+(x1-0.5)**2+3
哪里:
0=
使用mystic,您可以相对直接地解决问题:

>>> def objective(x):
...     return (x[0] - 1.5)**2 + (x[1] - 0.5)**2 + 3
... 
>>> bounds = [(0,None)]*2
>>> equations = """
... x1 < 4.1 - x0
... """
>>> 
>>> from mystic.symbolic import generate_penalty, generate_conditions
>>> pf = generate_penalty(generate_conditions(equations))
>>> 
>>> from mystic.constraints import integers
>>> 
>>> @integers()
... def round(x):
...   return x
... 
>>> from mystic.solvers import diffev2
>>> from mystic.monitors import VerboseMonitor
>>> 
>>> result = diffev2(objective, x0=bounds, bounds=bounds, penalty=pf, constraints=round, npop=40, gtol=100, disp=True, full_output=True, itermon=VerboseMonitor())
Generation 0 has ChiSquare: 9364567.500000
Generation 10 has ChiSquare: 7021.500000
Generation 20 has ChiSquare: 3.500000
Generation 30 has ChiSquare: 3.500000
Generation 40 has ChiSquare: 3.500000
Generation 50 has ChiSquare: 3.500000
Generation 60 has ChiSquare: 3.500000
STOP("ChangeOverGeneration with {'tolerance': 0.005, 'generations': 100}")
Optimization terminated successfully.
         Current function value: 3.500000
         Iterations: 67
         Function evaluations: 2400
>>> 
>>> print(result[0])
[2. 0.]
def目标(x): ... 返回(x[0]-1.5)**2+(x[1]-0.5)**2+3 ... >>>界限=[(0,无)]*2 >>>方程式=”“ …x1<4.1-x0 ... """ >>> >>>从mystic.symbolic导入生成惩罚,生成条件 >>>pf=生成惩罚(生成条件(方程式)) >>> >>>从mystic.constraints导入整数 >>> >>>@integers() ... def轮(x): ... 返回x ... >>>从mystic.solvers导入 >>>从mystic.monitors导入VerboseMonitor >>> >>>结果=差异v2(目标,x0=边界,边界=边界,惩罚=pf,约束=轮,npop=40,gtol=100,disp=真,完整输出=真,itermon=详细监视器() 第0代拥有ChiSquare:9364567.500000 第10代拥有ChiSquare:7021.500000 第20代拥有3.500000平方米 第30代拥有ChiSquare:3.500000 第40代拥有ChiSquare:3.500000 第50代拥有3.500000平方米 第60代拥有3.500000平方米 停止(“具有{'tolerance':0.005,'generations':100}的转换生成”) 优化已成功终止。 当前功能值:3.500000 迭代次数:67 功能评估:2400 >>> >>>打印(结果[0]) [2. 0.]

Mystic还具有逻辑运算符来耦合约束和惩罚,以及将潜在解决方案限制为离散值、唯一值等的约束。

在不了解更多最小化问题的情况下,我会尝试使用分支和边界。我应该提到我是Mystic的作者。谢谢,惊人的解释嘿!太酷了!非常感谢!我想知道:由于您使用“round”,解算器将浪费大量时间检查参数的等效数字(例如1.6和1.7)。我假设没有办法保存解算器这个额外的练习,对吗?另一方面:使用“int”而不是“round”是否会在性能上有所不同?不确定哪种性能更好,
round
int
。是的,您实际上可以轻松保存解算器,因为它是可序列化的。您可以使用解算器的类接口,而不是函数接口——这就是
DifferentiveEvolutionSolver2
类中的
SaveSolver
方法(而不是
DifferentiveV2
),在
mystic
中,约束是搜索空间的映射/过滤(即坐标变换),而当违反约束时,惩罚是成本的增加。因此,约束是“硬”的,惩罚是“软”的。使用
round
作为约束,基本上将强制解算器仅搜索整数空间。