如何在求解多个变量的同时提高Python优化速度

时间:2017-07-12 18:47:49

标签: python optimization scipy

我试图在解决静态模拟时获得24个变量的值。每个变量代表24条线的长度,我试图通过这种优化获得线上的预设张力。改变一根电线的长度会影响所有其他电线的张力。

目前我正在使用scipy.optimize模块中的Nelder-Mead方法的最小化函数。我的目标函数是预设张力与实现的张力值之间的绝对差值之和(使用商业软件以objfn计算)。

即使经过3000次迭代,求解器也无法找到足够接近的解。当涉及这些许多变量时,应该使用什么优化方法的任何建议,它们需要改变±5,精度为0.01。

import OrcFxAPI
import os
import numpy as np
import scipy as sp
from scipy.optimize import minimize

#-------------------------------------------------------------------------------
fileName = 'Jetty_Mooring.dat'
model = OrcFxAPI.Model(fileName)


# Target Pretension Values
#-------------------------------------------------------------------------------
target_pretensions = {'Line1': 91.0,'Line2': 91.0,'Line3': 91.0,'Line4': 49.0,
                      'Line5': 49.0,'Line6': 49.0,'Line7': 59.0,'Line8': 60.0,
                      'Line9': 60.0,'Line10': 68.0,'Line11': 68.0,'Line12': 68.0,
                      'Line13': 57.0,'Line14': 57.0,'Line15': 57.0, 'Line16': 55.0,
                      'Line17': 55.0,'Line18': 54.0,'Line19': 48.0, 'Line20': 48.0,
                      'Line21': 48.0,'Line22': 89.0,'Line23': 88.0, 'Line24': 89.0,
                      'Fender 1': - 200.0,'Fender 2': - 202.0, 
                      'Fender 3': - 206.0, 'Fender 4': - 207.0}

def objfn(wire_lengths):


    for i in range(24):
        line = model['Line' + str(i+1)]
        line.Length[0] = wire_lengths[i]

    try:
        model.CalculateStatics()


        # difference between targe and achieved pretension
        diff = 0
        achieved_pretension = {}
        for i in range(24):
            line = model['Line' + str(i+1)]
            pretension = line.StaticResult('Effective Tension', OrcFxAPI.oeEndA)
            achieved_pretension['Line' + str(i+1)] = pretension
            diff = diff + abs(target_pretensions['Line' + str(i+1)] 
                                    - achieved_pretension['Line' + str(i+1)])

        for i in range(4):
            fender = model['Fender ' + str(i+1)]
            pretension = fender.StaticResult('Tension')
            achieved_pretension['Fender '+ str(i+1)] = pretension
            diff = diff + abs(target_pretensions['Fender ' + str(i+1)] 
                                    - achieved_pretension['Fender ' + str(i+1)])

    except:
        print('OrcaFlex Static calculation not converged.')
        #input('>')
        return 1E8  # Returning a very large number in case of error

    return diff

# Initial condition
x0 = {'Line1': 48.3089,'Line2': 46.7486,'Line3': 45.6178,
                       'Line4': 10.2308,'Line5': 8.0667,'Line6': 6.8685,
                       'Line7': 46.6303,'Line8': 48.7554,'Line9': 50.5218,
                       'Line10': 33.3988,'Line11': 31.5107,'Line12': 29.5331,
                       'Line13': 31.9916,'Line14': 34.0526,'Line15': 35.8218, 
                       'Line16': 48.4918,'Line17': 46.8255,'Line18': 44.8937,
                       'Line19': 8.5358, 'Line20': 8.3543, 'Line21': 8.9467,
                       'Line22': 44.2500,'Line23': 45.7275, 'Line24': 47.50}
x0=list(x0.values())

# Nelder-Mead
result = minimize(objfn, x0, method = 'Nelder-Mead', options = {'disp': True,'ftol':0.001,'eps':0.1})


print(result)
编辑:由于很多评论者想看到目标函数,我在这里添加了整个代码。请注意,运行模型Jetty_Mooring.dat需要软件OrcaFlex才能获得目标函数中使用的结果。但是,这应该让人对这个问题有所了解。

0 个答案:

没有答案