Python 中的优化问题 - 比如 Goal Seek
Optimization problem in Python - like Goal Seek
我刚刚开始使用 Python 并且 运行 遇到了一个我认为应该很简单但我似乎无法弄清楚的挑战。在 Excel 中有一个 Goal Seek 选项,您可以在其中通过更改另一个值来优化一个值。我想知道是否可以在 Python 中有效地解决类似的优化问题,但能够一次更改多个值。
一个最小的例子:
我有两个数组
x = np.array([2, 3, 5, 6, 2, 2])
y = np.array([3, 2, 1, 4, 4, 2])
我试图在 y 中找到将以下公式的结果设置为 5 的值,仅使用值 [1, 2, 3]/
np.sqrt(sum((x-y)**2))
我知道正确的值应该是:
[1, 1, 2, 3, 1, 1]
我意识到可能有多种解决方案,因此能够对此设置一些限制会很好。
是否有任何特定的软件包可以让我这样做?上面只是一个玩具示例,在这种情况下,我可以尝试 [1, 2, 3] 的所有可能组合,但我真的在寻找可以扩展到更大数据集的东西。
使用 scipy.optimization 包中的 fsolve。
https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fsolve.html
你应该像这样定义 6 个参数:
# z = [ z1, z2, z3, z4, z5, z6]
z = x - y
roots = fsolve(func, z)
def func(z):
return [np.sqrt(sum(z**2))-5, 0, 0, 0, 0, 0]
与root
的关系越来越近。但无法弄清楚如何 select 只有 1,2 和 3.
import numpy as np
import scipy.optimize as opt
x = np.array([2, 3, 5, 6, 2, 2])
y = np.array([1, 1, 1, 1, 1, 1])
def func(y):
x = np.array([2, 3, 5, 6, 2, 2])
z = np.sqrt(np.sum((x-y)**2)) - 5
return np.zeros(x.shape[0],) + z
r = opt.root(func, x0=y, method='hybr')
print(r.x)
# array([1.51287563, 2.93792864, 2.41974376, 1.82313836, 1.49719936, 1.36584456])
print(np.sqrt(np.sum((x-r.x)**2)))
# 5.0
这是一个工作进展。我得想办法把它限制在1、2、3,等我突破了再更新我的答案。
更新
要使用任何给定的数组,
X = np.array([3, 4, 5, 6, 7])
y = np.array([1, 1, 1, 1, 1])
def func(y, given=X):
z = np.sqrt(np.sum((given-y)**2)) - 5
return np.zeros(given.shape[0],) + z
r = opt.root(func, x0=y, method='hybr')
print(r.x)
# array([1.97522498 3.47287981 5.1943792 2.10120135 4.09593969])
print(np.sqrt(np.sum((X-r.x)**2)))
# 5.0
我刚刚开始使用 Python 并且 运行 遇到了一个我认为应该很简单但我似乎无法弄清楚的挑战。在 Excel 中有一个 Goal Seek 选项,您可以在其中通过更改另一个值来优化一个值。我想知道是否可以在 Python 中有效地解决类似的优化问题,但能够一次更改多个值。
一个最小的例子:
我有两个数组
x = np.array([2, 3, 5, 6, 2, 2])
y = np.array([3, 2, 1, 4, 4, 2])
我试图在 y 中找到将以下公式的结果设置为 5 的值,仅使用值 [1, 2, 3]/
np.sqrt(sum((x-y)**2))
我知道正确的值应该是:
[1, 1, 2, 3, 1, 1]
我意识到可能有多种解决方案,因此能够对此设置一些限制会很好。
是否有任何特定的软件包可以让我这样做?上面只是一个玩具示例,在这种情况下,我可以尝试 [1, 2, 3] 的所有可能组合,但我真的在寻找可以扩展到更大数据集的东西。
使用 scipy.optimization 包中的 fsolve。
https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fsolve.html
你应该像这样定义 6 个参数:
# z = [ z1, z2, z3, z4, z5, z6]
z = x - y
roots = fsolve(func, z)
def func(z):
return [np.sqrt(sum(z**2))-5, 0, 0, 0, 0, 0]
与root
的关系越来越近。但无法弄清楚如何 select 只有 1,2 和 3.
import numpy as np
import scipy.optimize as opt
x = np.array([2, 3, 5, 6, 2, 2])
y = np.array([1, 1, 1, 1, 1, 1])
def func(y):
x = np.array([2, 3, 5, 6, 2, 2])
z = np.sqrt(np.sum((x-y)**2)) - 5
return np.zeros(x.shape[0],) + z
r = opt.root(func, x0=y, method='hybr')
print(r.x)
# array([1.51287563, 2.93792864, 2.41974376, 1.82313836, 1.49719936, 1.36584456])
print(np.sqrt(np.sum((x-r.x)**2)))
# 5.0
这是一个工作进展。我得想办法把它限制在1、2、3,等我突破了再更新我的答案。
更新
要使用任何给定的数组,
X = np.array([3, 4, 5, 6, 7])
y = np.array([1, 1, 1, 1, 1])
def func(y, given=X):
z = np.sqrt(np.sum((given-y)**2)) - 5
return np.zeros(given.shape[0],) + z
r = opt.root(func, x0=y, method='hybr')
print(r.x)
# array([1.97522498 3.47287981 5.1943792 2.10120135 4.09593969])
print(np.sqrt(np.sum((X-r.x)**2)))
# 5.0