利用IMSL库中的函数nconf求解一个约束非线性优化问题。我简化了问题,以描述所发生的错误。
目标函数为log(x1 * x2 - x3 ^ 2)。约束是x1 * x2 - x3 ^ 2 > 0。fortran代码如下所示。
program main
use IMSL
integer IBTYPE, IPRINT, M, MAXITN, ME, N
parameter (IBTYPE = 0, IPRINT = 0, M = 1, MAXITN = 100, ME = 0, N = 3)
real FVALUE, X(N), XGUESS(N), XLB(N), XSCALE(N), XUB(N)
external FCN
data XGUESS/10.0E0, 10.0E0, 2.0E0/, XSCALE/3*1.0E0/
data XLB/1.0E-6, 1.0E-6, 1E-6/, XUB/50, 50, 50/
!open(44, file = "test.txt", status = "unknown")
call NCONF(FCN, M, ME, N, XGUESS, IBTYPE, XLB, XUB, XSCALE, IPRINT, MAXITN, X, FVALUE)
!write(*, *) X
end program
subroutine FCN(M, ME, N, X, ACTIVE, F, G)
integer M, ME, N
real X(3), F, G(*)
logical ACTIVE(*)
ACTIVE(1) = .TRUE.
!write(44, *) x
F = log(x(1) * x(2) - x(3) ** 2)
!write(44, *) F
IF(ACTIVE(1)) G(1) = X(1) * x(2) - x(3) ** 2
return
end subroutine当我运行代码时,约束不起作用。nconf确实搜索了一个生成x1 * x2 - x3 ^ 2 < 0的(x1, x2, x3),但是则抛出了一个异常。x1 * x2 - x3 ^ 2在log函数中。不可能是阴性的。如果约束有效,x1 * x2 - x3 ^ 2不应该是负的。我不知道nconf函数搜索点x以及约束是如何工作的。
发布于 2014-03-20 12:24:16
详细阐述我的评论,求解者了解约束的唯一方法是“越界”,因此您应该非常期待超出界限的值并优雅地处理它们。
一种典型的方法是:
G(1) = X(1) * x(2) - x(3) ** 2
if(g(1).gt.0)then
f=log(g(1))
else
f=-10.e30
endif在越界情况下,您返回的内容可能并不重要,但是检查imsl例程的docs,看看它是否说明了这一点。
顺便提一句,请注意,由于硬编码了active(1)=.true.,所以不需要if(active(1))..构造。
https://stackoverflow.com/questions/22524046
复制相似问题