遗传编程健身功能

时间:2013-03-12 10:17:24

标签: r computational-geometry coordinate-transformation genetic-programming

我正在尝试在遗传编程中编写一个适应度函数来扩大多边形内部点所占的面积。在多边形的中心附近有一些点,我想从中心扩展这些点,直到它在多边形内部。

我正在使用多边形内部点占据的区域与外部多边形区域之间的差异,并尝试在适应度函数中将其最小化。但我不知道如何使用它来改变点的坐标,然后重新计算区域的差异并迭代地进行。我已经给出了输入和输出的样子。

提前致谢。

这是我到目前为止编写的代码。

require(rgp)
require(splancs)
require(grDevices)
functionSet1 <- functionSet("+", "*", "-", "/","^")
inputVariableSet1 <- inputVariableSet("x","y")
constantFactorySet1 <- constantFactorySet(function() rnorm(1))

outpolygon<-matrix(c(3.061188,2.517408,0.523754,-0.258800,0.981104,4.036885,
                     3.061188,4.069070,4.069070,2.695074,0.485581,-2.129055,
                     -2.653607,4.069070),nrow=7,byrow=F)
inpoints<-matrix(c(2.637644,-0.4456578,2.160003,0.8553066,1.501256,1.3137518,2.352020,-0.2643815,
                   1.254139,1.2241712,1.918191,0.6595725,1.453478,0.9153824,1.900110,1.0607272,
                   1.648038,0.6847361,2.194931,2.2842159),nrow=10,byrow=T)

plot(-10:10,xlim=c(-5,5),ylim=c(-5,5))
polygon(outpolygon[,1],outpolygon[,2])
points(inpoints[,1],inpoints[,2])

fitnessFunction1 <-  function(f){
  if(all(point.in.polygon(inpoints[,1],inpoints[,2],outpolygon[,1],outpolygon[,2])!=0)){
    rmse(areapl(inpoints[chull(inpoints[,1],inpoints[,2]),]),areapl(cbind(outpolygon[,1],outpolygon[,2])[chull(outpolygon[,1],outpolygon[,2]),]))
  }else{
    rmse(1000,0)
  }
}

gpResult1 <- geneticProgramming(functionSet=functionSet1,
                                inputVariables=inputVariableSet1,
                                constantSet=constantFactorySet1,
                                fitnessFunction=fitnessFunction1,    
                                stopCondition=makeTimeStopCondition(10))


best1 <- gpResult1$population[[which.min(sapply(gpResult1$population,
                                                fitnessFunction1))]]

enter image description here enter image description here

1 个答案:

答案 0 :(得分:2)

有几种方法可以做到这一点。最简单的方法实际上是GA,而不是GP。在这种情况下,您将有一个分为四边形的整数数组,以便:

[funcx1,valx1,funcy1,valy1,funcx2,valx2,funcy2,valy2,...,funcxn,valxn,funcyn,valyn]

你的拟合函数将取funcxi的模数并得到相应的函数。然后,您将valxi中的数字应用于该函数到相应的x值。给定返回的点数,你可以按照你所说的计算区域,如果它们超过相应的区域(负常数或逐个因子),则惩罚个体。

或者,如果由于某种原因必须使用GP,则有两条主要路线。如果您希望代码是通用的(即,您相同的进化代码块应用于每个点;注意:这样更难),您将需要更多非终端(即函数) 。我可能会至少添加if语句。自动定义的函数(ADF)也很好,某种分组函数就像Lisp中的progn一样。可以说,GA方法更容易。

另一种方法是使用更结构化的GP并改为添加赋值函数。

GPnonterminals:+, - ,*,/,^,=(所有向量函数)

GPterminals:point1,point2,...,pointn,randompoint()

使用Lispy结构,您的代码看起来像:

(*(=(= point2(* randompoint()(= point2 randompoint())))point1)randompoint())

然后,当你评估它时,你将从叶子到根的所有赋值,用较高的值覆盖较低的点。因此,在上面的示例中,point2将被指定为随机点(可能是坏的)。结果将乘以一个随机点,然后用结果覆盖对point2的原始赋值。同样的结果将被分配给point1,最后,它将乘以randompoint。但是,由于没有进一步的分配,最终的价值将被丢弃。

这是“更有条理”的原因是你必须确保赋值永远不会发生在除点之外的任何事情上。基于语法或语法指导的GP特别擅长于此。我将把你引用到Whigham(1995)的这篇论文来解释它们:

http://sc.snu.ac.kr/courses/2007/fall/pg/aai/GP/whigham/whigham95grammaticallybased.pdf

如果使用GP,在任何一种情况下,您都必须为上面描述的格式编写一些列表遍历函数。我还建议使用点和向量函数而不是x和y,以便你有更少的终端来跟踪(并且你的程序树将更小/处理更快)。哦,并确保randompoint()函数返回一个特定的点(即,确保你之前评估它你把它放入染色体或代码会产生不一致的结果 - 非常糟糕,那) 。并使这些可能点的范围合理(即,如果你在10平方的空间内,不要达到100)。

你还有一段路要走,但希望能指出你正确的方向。