Alglib minnl c возвращает ответ вне ограничений - PullRequest
4 голосов
/ 06 мая 2020

Я пытаюсь реализовать простую минимизацию с ограничением квадратичного c неравенства и ограничением линейного равенства, а также с нижними и верхними границами. Моя проблема заключается в следующем:

min: x1 * (- 0,00498) + x2 * 0,05656

u. c. :

  • x1 ^ 2 * 0,00001048 + 2 * x1 * x2 * 0,001431 + x2 ^ 2 * 0,6737996 <= 0,0084050 </li>
  • x1 + x2 = 1,0
  • 0
  • 0

После реализации в F # с использованием Alglib кажется, что ограничения не соблюдаются. Ни сумма x1 + x2 не равна 1,0, ни дисперсия не меньше 0,0084. Хотя нижняя и верхняя границы соблюдаются, моя целевая функция с x2 улучшена (ниже), чем с x0. Я считаю, что у меня проблема с моей формулировкой ограничений, но я не могу понять, какое именно.

l

let nsfunc2_jac(x:float[]) (fi:float[])(jac:float[,])=
   fi.[0] <- -(x.[0]*-0.00498+x.[1]*0.05656)
   fi.[2] <- x.[0]+x.[1]+x.[2]-1.0
   fi.[1] <- x.[0]*x.[0]*0.00001048 + 2.0*x.[0]+x.[1]*0.001431 + x.[1]*x.[1]*0.6737996-0.0084050
   jac.[0,0] <- -0.00498
   jac.[0,1] <- 0.05656
   jac.[2,0] <- 1.0
   jac.[2,1] <- 1.0
   jac.[1,0] <- 2*x.[0]*0.00001048 + 2*x[1]*0.001431
   jac.[1,1] <- 2*x.[0]*0.001431 + 2+x[1]*0.6737996

let mutable state2 = new alglib.minnlcstate()
let mutable rep2 = new alglib.minnlcreport()
let mutable nrep = new alglib.ndimesional_rep(func2)
let x0 = [|0.8999, 0.1001|]
alglib.minnlccreate(2,x0, &state2)
alglib.minnlcsetalgoaul(state2, 1000.0, 15.0)
alglib.minnlsetcond(state2, 0.000001,10.0)
alglib.minnlcsetscale(state2, [|1.0,1.0|])
alglib.minnlcsetprecexactlowrank(state2, 5.0)
alglib.minnlcsetnlc(state2, 1,1)
alglib.minnlcsetbc(state2, [|0.0,0.0|], [|0.9,0.9|])

alglib.minnlcoptimize(state2, jac, nrep, None)
let x2, rep = alglib.minnlcresults(state2)
let var = x2.[0]*x2.[0]*0.00001048 + 2.0*x2.[0]+x2.[1]*0.001431 + x2.[1]*x2.[1]*0.6737996
printfn "Variance: %s" var.ToString()

Я получаю Var = 0,53 значительно выше целевого значения 0,0084050. Фактически, после первой итерации мои ограничения равенства и неравенства нарушаются, и алгоритм никогда не возвращается в диапазон.

Тревожнее, я получаю ответ TerminationType = 1 -> OK

...