最小化多变量函数

问题描述 投票:1回答:2

我在三维空间中有两个二次曲面。

  • 一张圆形双曲面 由xt,yt,zt,rt描述
  • 圆形抛物面 由xs,ys,zs,rs描述

我想尽量减少两个物体之间的距离。函数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个参数的最佳值,以最小化函数的值?

python optimization scipy surface
2个回答
2
投票

看起来你想要改变所有四个参数。您将它们的初始值传递为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不变。这听起来不像你想要的。你已经使用ABC作为全局常量。

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词典中的大多数项目都解释如下:

https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.OptimizeResult.html#scipy.optimize.OptimizeResult

final_simplex是这种最小化方法的特殊输出。


0
投票
res = minimize(distance,
           x0[0],
           args=(*x0[1:],),
           method='nelder-mead')

我想这就是你想要的。

© www.soinside.com 2019 - 2024. All rights reserved.