我正在尝试找到一种(相对)快速的方法来在给定约束和界限的情况下最小化自然数集上的函数。我知道函数的数学形式及其约束,因此蛮力方法似乎很慢,而且不是很优雅。解决此问题的最佳方法是什么?
基本上,我正在尝试使用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或一些神秘主义者来解决问题的方法?有什么建议吗?
答案 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还具有逻辑运算符,用于结合约束和惩罚,以及将潜在解限制为离散值,唯一值等的约束。