我的目标函数考虑椭圆弧长。在目标函数中,我使用 uniroot 为 nsga提供的半长a和弧角找到半短轴b 。
我编写了一个约束函数来确保提供给 uniroot 的限制是相反的符号......但它不起作用。程序崩溃是因为 f() 值不是相反的符号。
我已经将程序简化为下面的示例......希望能帮助它工作。谢谢你。
library(RConics)
library(mco)
###############################################################
#FUNCTIONS
###############################################################
restricts<-function(invec,len){
lwr<-sign(get_b(1, as.numeric(invec[1]), len, as.numeric(invec[2])))
uppr<-sign(get_b(as.numeric(invec[1]), as.numeric(invec[1]), len, as.numeric(invec[2])))
restrictions <- logical(1)
restrictions[1] <- (lwr != uppr)
return (restrictions)
}
objective<-function(invec, len){
a<-as.numeric(invec[1])
theta=as.numeric(invec[2])
b_out<-uniroot(get_b,c(1,a),a=a,len=len,theta=theta)
b<-b_out$root
ps<- c(
a*cos(d2r(90+theta)),
b*sin(d2r(90+theta))
)
end<- atan(-b*cot(d2r(180+(90-theta)))/a) - pi/2+pi/2
rot <- 0.52-end
final<- RotMat(rot)%*%ps
return(abs(final[2]))
}
r2d<-function(theta) theta*180/pi
d2r<-function(theta) theta*pi/180
RotMat<-function(theta) rbind(c(cos(theta),-sin(theta)),c(sin(theta),cos(theta)))
get_b<-function(b,a,len,theta){
return(
len-arcLengthEllipse(
p1 = c(0,b),
p2 = c(a*cos(d2r(90+theta)), b*sin(d2r(90+theta))),
saxes = c(a,b),
n = 5)
)
}
###############################################################
#MAIN
###############################################################
mods<-nsga2(objective, idim=2, odim=1,
constraints = restricts,
cdim=1,
generations=10, popsize=100,
cprob=0.9, cdist=1,
mprob=0.2, mdist=20,
lower.bounds = c(130,1), #70.6, 86.6
upper.bounds = c(203,90),
len=204)