我完全是在即兴做这件事……但这就是我的做法mystic
。
>>> equations = """
... 3.*x0 + 5.*x1 + 7.*x2 + 9.*x3 = 1.*x0 + 2.*x1 + 3.*x3
... """
>>> bounds = [(0,None)]*4
>>>
>>> def objective(x):
... return x[0]**2 + 2*x[1] - 2*x[2] - x[3]**2
...
>>> 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
>>> result = diffev2(objective, x0=bounds, bounds=bounds, penalty=pf, constraints=round, npop=20, gtol=50, disp=True, full_output=True)
Optimization terminated successfully.
Current function value: 0.000000
Iterations: 121
Function evaluations: 2440
>>> result[0]
array([0., 0., 0., 0.])
现在稍微修改方程...
>>> equations = """
... 3.*x0 + 5.*x1 + 7.*x2 + 9.*x3 = 5 + 1.*x0 + 2.*x1 + 3.*x3
... """
>>> pf = generate_penalty(generate_conditions(equations))
>>> result = diffev2(objective, x0=bounds, bounds=bounds, penalty=pf, constraints=round, npop=20, gtol=50, disp=True, full_output=True)
Optimization terminated successfully.
Current function value: 3.000000
Iterations: 102
Function evaluations: 2060
>>> result[0]
array([1., 1., 0., 0.])
如果您想要二进制变量而不是整数,那么您可以使用bounds = [(0,1)]*4
或替换@integers()
为@discrete([0.0, 1.0])
.
虽然上面的结果不太有趣,但在 mystic 的 GitHub 上,有一些经过深思熟虑的整数规划和广义约束的全局优化示例:
https ://github.com/uqfoundation/mystic/blob/master/examples2 /integer_programming.py
https://github.com/uqfoundation/mystic/blob/master/examples2/olympic.py