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

时间:2019-07-26 14:58:34

标签: python scipy-optimize mystic discrete-optimization

我正在尝试找到一种(相对)快速的方法来在给定约束和界限的情况下最小化自然数集上的函数。我知道函数的数学形式及其约束,因此蛮力方法似乎很慢,而且不是很优雅。解决此问题的最佳方法是什么?

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

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

from scipy import optimize

x0 = [0,0]
cons = ({'type': 'ineq', 'fun': lambda x: 0.4 - x[1]})
bounds = ((0,None),(0,None))
fun = lambda x: (x[0]-1.5)**2 + (x[1]-0.5)**2 + 3

res = optimize.minimize(fun, x0=x0, bounds=bounds, constraints=cons)
print(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)
min_val = fun(min_idx)

print(min_idx,min_val)

(我知道我可以通过从xr中排除这些值来强加它们,但是对于我所想到的实际情况来说,这似乎很少,也不实用)

所以我期望有某种不同的最小化方法,例如scipy.optimize.basinhopping或一些神秘主义者来解决问题的方法?有什么建议吗?

1 个答案:

答案 0 :(得分:0)

我稍微修改了您的问题,使其变得有点困难...

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

  Where: 
            0 =< x0
            0 =< x1 < 4.1 - x0
            x0,x1 are integers

借助神秘主义者,您可以相对直接地解决问题:

>>> 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.]

Mystic还具有逻辑运算符,用于结合约束和惩罚,以及将潜在解限制为离散值,唯一值等的约束。

相关问题