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

2024-10-01 09:22:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图在求解静态模拟时获得24个变量的值。每个变量代表24根钢丝的长度,我试图通过这个优化来获得预先设定的钢丝张力。更改一根导线的长度会影响其他所有导线的张力。在

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

即使经过3000次迭代,解算器也无法找到足够接近的解。当涉及到这么多变量,并且它们需要以0.01的精度变化±5时,有什么关于优化方法的建议吗。在

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。不过,这应该能让我们对这个问题有所了解。在


Tags: 函数inimportmodellinediffscipystr