2013-03-13 40 views
0

我想找到幾個元素的位置[X,Y,Z],以便在所需的點處具有全局重心。優化 - Python和Scypi.minimize

爲此,我定義2類:其中存儲元件的質量和位置

  • 平面這需要元件的列表,並根據所設置的元件的可以計算其重心

    • 元件。

    我還定義了一個誤差函數,用於計算實際的全球重心距平面的元素集和所需的重心之間的差異。

    爲了儘量減少這個功能,我想用Nelder-Mead Simplex算法使用scypi.minimize函數。

    我把每個元素的座標放入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}) 
    
  • 回答

    0

    你的目標函數返回一個列表,而minimize預計標。您需要首先設置問題,並通過最小化向量值函數來指定您的意思。

    0

    您應該能夠將每個座標分量(x,y和z)分別最少運行三次。然後修改calculErreurPosCDG以處理單個值而不是矢量,然後使其工作。那麼它只會處理標量。

    補充說明:最好在Python中以大寫字母開頭,並用小寫字母函數啓動Python中的Classes名稱。

    +0

    根據您的建議,這裏是我做了什麼: 我修改X0爲了只有X座標 我這樣做了X,Y取,Z 我修改了objectiv功能:calculErreurPosCDG與平面類,爲了後重新計算重心每次迭代 但事實是,它的發散,即使所有的元素都已經處於一個很好的位置(參見Y座標) '高清calculErreurPosCDGX(X0): global positionCDGconsigne,plane1 i = 0 for element in: el.position [0] = x0 [i] i + = 1 plane1.update() print plane1.cdg return positionCDGconsigne [0] -plane1.cdg [0]' – CrH 2013-03-13 15:06:20