我有一个问题,我需要最小化一个局部仿射函数,我选择使用WORHP (稍后局部仿射属性将被其他局部条件取代)。函数的值以及导数和hessian (这是微不足道的)作为用户输入提供,计算速度非常快。我有简单的框约束,即所有变量都应该在0和1之间,没有其他约束。我认为这是一个相当容易的问题。尽管如此,WORHP需要迭代超过350次,这对于简单的问题来说是相当高的计算时间。对于这种情况,有没有办法选择更好的参数?下面给出了我使用的python代码(输入值由另一个进程计算)。
def worhp_minimize(n, f, df, hmf, xl, xu, init_x):#f:R^n -> R, df: R^n -> R^n, g:R^n -> R^m, gl in R^m, gu in R^m, dg in R^nxm, hmf:R^n -> R^k, hmg: R^(n+m) -> R^k
def vectorize(attribute):
return [float(attribute[i]) for i in range(0,len(attribute))]
def assign(attribute,list):
for i in range(0,len(list)):
if list[i] == "inf":
attribute[i] = par.infty
elif list[i] == "-inf":
attribute[i] = -par.infty
else:
if isinstance(list[i],int):
attribute[i] = list[i]
else:
attribute[i] = float(list[i])
def user_f(opt, wsp, par, cnt):
opt.f = wsp.scale_obj * f(vectorize(opt.x))
def user_df(opt, wsp, par, cnt):
assign(wsp.df.val, wsp.scale_obj*df(vectorize(opt.x)))
#def user_dg(opt, wsp, par, cnt):
# assign(wsp.dg.val, dg(vectorize(opt.x)))
def user_hm(opt, wsp, par, cnt):
hess = wsp.scale_obj * hmf(vectorize(opt.x))
l = len(hess)
index = 0
for j in range(0,l):
wsp.hm.val[l*(l-1)//2 + j] = hess[j][j]
for i in range(j,l):
wsp.hm.val[index] = hess[i][j]
index +=1
if worhp.check_version(worhp.MAJOR, worhp.MINOR, worhp.PATCH):
exit(1)
opt = worhp.OptVar()
wsp = worhp.Workspace()
par = worhp.Params()
cnt = worhp.Control()
worhp.pre_init(opt, wsp, par, cnt)
worhp.init_params(par)
par.NLPprint = 1
status = worhp.read_params_no_init("worhp.xml", par)
if status == worhp.DATA_ERROR or status == worhp.INIT_ERROR:
exit(1)
opt.n = n
opt.m = 0
worhp.init(opt, wsp, par, cnt)
if cnt.status != worhp.FIRST_CALL:
print("Main: Initialisation failed.")
exit(1)
assign(opt.x, init_x)
assign(opt.Lambda, [0.]*n)
assign(opt.xl, xl)
assign(opt.xu, xu)
while cnt.status < worhp.TERMINATE_SUCCESS and cnt.status > worhp.TERMINATE_ERROR:
if worhp.get_user_action(cnt, worhp.Action.CALL_WORHP):
#print("call worhp")
worhp.worhp(opt, wsp, par, cnt)
if worhp.get_user_action(cnt, worhp.Action.ITER_OUTPUT):
#print("iter output")
worhp.iteration_output(opt, wsp, par, cnt)
worhp.done_user_action(cnt, worhp.Action.ITER_OUTPUT)
if worhp.get_user_action(cnt, worhp.Action.EVAL_F):
#print("eval f")
user_f(opt, wsp, par, cnt)
worhp.done_user_action(cnt, worhp.Action.EVAL_F)
if worhp.get_user_action(cnt, worhp.Action.EVAL_DF):
#print("eval df")
user_df(opt, wsp, par, cnt)
worhp.done_user_action(cnt, worhp.Action.EVAL_DF)
if worhp.get_user_action(cnt, worhp.Action.EVAL_HM):
#print("eval hm")
user_hm(opt, wsp, par, cnt)
worhp.done_user_action(cnt, worhp.Action.EVAL_HM)
if worhp.get_user_action(cnt, worhp.Action.FIDIF):
#print("fidif")
worhp.fidif(opt, wsp, par, cnt)
# No done_user_action!
worhp.status_msg(opt, wsp, par, cnt)
return opt.f, vectorize(opt.x)发布于 2020-05-28 19:13:18
如果Hessian为0,WORHP将应用一些正则化来获得正确定性,这可能会减慢收敛速度。您可以尝试将参数StartBettsTau设置为一个非常小的值,如1e-16,以避免许多正则化。
https://stackoverflow.com/questions/60523098
复制相似问题