我在三维空间中有两个二次曲面。
我想尽量减少两个物体之间的距离。函数distance()
有4个变量 - alpha,beta,zt和zs。目标是找到这4个变量的这些值,函数返回最小可能值。
请考虑以下代码。
import numpy as np
from scipy.optimize import minimize
A = 1; B = 1; C = 1; D = 1; Z = 0;
def distance(alpha,beta,zt,zs):
"""distance between points in 2 quadric surfaces in 3D space"""
rt = (A/B) * np.sqrt(B**2 + (zt-C)**2)
xt = rt * np.cos(alpha)
yt = rt * np.sin(alpha)
rs = D * np.sqrt(zs-Z)
xs = rs * np.cos(beta)
ys = rs * np.sin(beta)
return (xt-xs)**2 + (yt-ys)**2 + (zt-zs)**2
x0 = np.array([0, 0, 0, 0])
res = minimize(distance,
x0,
method='nelder-mead')
代码给我以下错误。
TypeError:distance()缺少3个必需的位置参数:'beta','zt'和'zs'
我发现所有documentation只使用单变量(一个变量)函数(如Rosenbrock函数),尽管它说它最小化了“多变量标量函数”。
如何让我的代码找到4个参数的最佳值,以最小化函数的值?
看起来你想要改变所有四个参数。您将它们的初始值传递为x0
,一个4元素数组。这就是minimize
将传递给distance
。这是对distance
的改变,应该适用于:
def distance(x):
"""distance between points in 2 quadric surfaces in 3D space"""
alpha,beta,zt,zs = x # unpack x into these 4 variables
rt = (A/B) * np.sqrt(B**2 + (zt-C)**2)
xt = rt * np.cos(alpha)
yt = rt * np.sin(alpha)
rs = D * np.sqrt(zs-Z)
xs = rs * np.cos(beta)
ys = rs * np.sin(beta)
return (xt-xs)**2 + (yt-ys)**2 + (zt-zs)**2
args
建议会改变alpha
并保持其他3不变。这听起来不像你想要的。你已经使用A
,B
,C
作为全局常量。
1115:~/mypy$ python3 stack55751317.py
final_simplex: (array([[-1.21456543, -1.21455458, 0.99997997, 0.99997757],
[-1.21457508, -1.21458998, 0.9999941 , 1.00000714],
[-1.21461728, -1.21460427, 1.00002695, 1.00001266],
[-1.21456081, -1.2145312 , 0.99996329, 0.99996864],
[-1.2146315 , -1.21462741, 1.00002628, 1.00004968]]), array([2.49380001e-10, 4.04824635e-10, 4.13486388e-10, 1.15131206e-09,
1.18130671e-09]))
fun: 2.4938000073954824e-10
message: 'Optimization terminated successfully.'
nfev: 295
nit: 172
status: 0
success: True
x: array([-1.21456543, -1.21455458, 0.99997997, 0.99997757])
x
看起来像结果,你可以用res['x']
访问。
这篇res
词典中的大多数项目都解释如下:
final_simplex
是这种最小化方法的特殊输出。
res = minimize(distance,
x0[0],
args=(*x0[1:],),
method='nelder-mead')
我想这就是你想要的。