2

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

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

提前致谢。

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

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))]]

在此处输入图像描述 在此处输入图像描述

4

1 回答 1

2

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

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

您的 fit 函数将采用 funcxi 的模数并获得相应的函数。然后,您将 valxi 中的数字应用于该函数到相应的 x 值。给定返回的点,您将按照您所说的计算面积,如果个人超过相应的区域(负常数或系数超过),则惩罚他们。

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

另一条路线是使用更结构化的 GP 并添加分配功能。

GP 非终结符:+、-、*、/、^、=(所有向量函数)

GP 终端:point1、point2、...、pointn、randompoint()

使用 Lispy 结构,您的代码将类似于:

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

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

这是“更有条理”的原因是您必须确保分配永远不会发生在点以外的任何事情上。基于语法或语法指导的全科医生特别擅长这一点。我将向您推荐 Whigham (1995) 的这篇论文,该论文解释了它们:

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

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

您还有一段路要走,但希望这会为您指明正确的方向。

于 2013-03-19T20:51:36.780 回答