我试图在解决静态模拟时获得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才能获得目标函数中使用的结果。但是,这应该让人对这个问题有所了解。