1

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

基本上,我试图从使用 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 或者神秘的东西来做这个把戏?有什么建议么?

4

1 回答 1

3

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

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

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

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

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

于 2019-07-28T22:13:21.980 回答