WORHP очень медленно на локально аффинной функции - PullRequest
0 голосов
/ 04 марта 2020

У меня есть проблема, когда мне нужно минимизировать локально-аффинную функцию, и я решаю использовать WORHP (позже локально-аффинное свойство будет заменено другими локальными условиями). Значение функции, а также производная и гессиан (что является тривиальным) предоставляется в качестве пользовательского ввода и вычисляется очень быстро. У меня есть простые ограничения коробки, то есть все переменные должны быть между 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...