0

我想找到几个元素的位置 [X,Y,Z] 以使全球重心位于所需的点。

为此,我定义了 2 个类:

  • 存储元素质量和位置的元素
  • 平面,它采用元素列表并可以根据元素集计算其重心。

我还定义了一个误差函数,它计算平面元素集的实际全局重心与所需重心之间的差异。

为了最小化这个函数,我想将该scypi.minimize函数与 Nelder-Mead Simplex 算法一起使用。

我将每个元素的坐标放入x0然后将x0误差函数作为参数传递给最小化。

我收到了这个我不明白的错误:

ValueError: setting an array element with a sequence. 

此外,根据我想要做的,您可能有更好的想法来解决/解决我的问题?

这是代码:

import numpy as np
from scipy.optimize import minimize

class plane(object):
  def __init__(self, elts):
    self.elements=elts
    self.TotalMasse=self.calc_masse(self.elements) 
    self.cdg = self.calc_CDG()

  def __getitem__(self):
    return self.elements,self.TotalMasse

  def calc_masse(self,elements):
    Lm=[]
    for el in elements:
      Lm.append(el.masse)
    return sum(Lm)

  def calc_CDG(self):
    Xcdg=0
    Ycdg=0
    Zcdg=0
    for el in self.elements:
      Xcdg+=el.masse*el.position[0]/self.TotalMasse
      Ycdg+=el.masse*el.position[1]/self.TotalMasse
      Zcdg+=el.masse*el.position[2]/self.TotalMasse
    return [Xcdg,Ycdg,Zcdg]

class element(object):
  def __init__(self, mass, pos):
    self.masse=mass
    self.position=pos

  def __getitem__(self):
    return self.masse, self.position



def calculErreurPosCDG(cdg):
    global positionCDGconsigne
    return [positionCDGconsigne[0]-cdg[0], positionCDGconsigne[1]-cdg[1],positionCDGconsigne[2]-cdg[2]]

battery = element(0.5,[0.5,1,1])
motor = element(0.2,[1,1,0])
servoL = element(0.01,[-0.7,1,0])
servoR = element(0.01,[0.7,1,0])
reciever = element(0.01,[0.1,1,1])

elements=[battery, motor, servoL, servoR, reciever]

positionCDGconsigne=[1,1,1]

plane1=plane(elements)

x0=np.array([])
for el in elements:
  x0= np.append(x0,[el.position])

res=minimize(calculErreurPosCDG,x0,method='nelder-mead', options={'xtol':1e-8,'disp':True})
4

2 回答 2

0

您应该能够分别对每个坐标组件(x、y 和 z)运行最小化 3 次。然后修改calculErreurPosCDG以处理单个值而不是向量应该使其工作。然后它将只处理标量。

补充说明:在 Python 中以大写字母开头的类名称和以小写字母开头的函数是一种很好的做法。

于 2013-03-13T14:04:45.590 回答
0

您的目标函数返回一个列表,而minimize需要一个标量。您需要首先设置您的问题,并通过最小化向量值函数来指定您的确切含义。

于 2013-03-13T13:37:13.197 回答