генетическое программирование фитнес-функция

Я пытаюсь написать фитнес-функцию в генетическом программировании, чтобы увеличить площадь, занимаемую точками внутри многоугольника. Рядом с центром многоугольника есть несколько точек, я хочу расширить эти точки от центра до тех пор, пока они не окажутся внутри многоугольника.

Я использовал разницу между площадью, занимаемой точками внутри многоугольника, и площадью внешнего многоугольника и пытался минимизировать ее в фитнес-функции. Но я не знаю, как использовать это, чтобы изменить координаты точек, а затем пересчитать разницу в площади и сделать это итеративно. Я дал, как должны выглядеть ввод и вывод.

Заранее спасибо.

Это код, который я написал до сих пор.

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

введите здесь описание изображениявведите здесь описание изображения


person user2092000    schedule 12.03.2013    source источник
comment
Похоже, вы уже определили хорошую фитнес-функцию - разницу между площадью многоугольника и площадью, занимаемой (выпуклой оболочкой) точек. Конечно, вы можете захотеть иметь какой-то отрицательный коэффициент, если точки лежат за пределами многоугольника. Похоже, ваш настоящий вопрос: каким должно быть генетическое представление точек и какие генетические операторы вы должны использовать для управления ими. Это более точно?   -  person Tom    schedule 12.03.2013
comment
Ты прав. Я прикрепил код сейчас. Я не могу сделать так, чтобы точки расширялись. Точки не меняются, потому что я не написал код для расширения точек. Я не знаю, как включить его в фитнес-функцию.   -  person user2092000    schedule 12.03.2013


Ответы (1)


Есть несколько способов сделать это. На самом деле проще всего было бы с GA, а не с GP. В этом случае у вас будет массив целых чисел, разбитых на четверки, так что:

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

Ваша подходящая функция будет принимать модуль funcxi и получать соответствующую функцию. Затем вы примените число в valxi к этой функции к соответствующему значению x. Учитывая возвращаемые баллы, вы должны рассчитать площадь, как вы сказали, и наказать человека, если он превысит соответствующую площадь (отрицательная константа или коэффициент на степень).

В качестве альтернативы, если вам по какой-либо причине необходимо воспользоваться услугами врача общей практики, есть два основных пути. Если вы хотите, чтобы код был универсальным (т. е. вы применяли один и тот же фрагмент кода к каждой точке; обратите внимание: это намного сложнее), вам потребуется больше нетерминалов (т. е. функций) . Я бы, вероятно, добавил как минимум операторы if. Автоматически определяемые функции (ADF) также были бы хороши и какая-то функция группировки, такая как progn из Lisp. Достаточно сказать, что метод GA намного проще.

Другой путь — использовать более структурированный GP и добавить вместо него функцию назначения.

GPnonterminals: +, -, *, /, ^, = (все векторные функции)

Терминалы GP: точка1, точка2, ..., точкаn, случайная точка()

Используя структуру Lispy, ваш код будет выглядеть примерно так:

(* (= (= точка2 (* случайная точка() (= точка2 случайная точка())))) точка1) случайная точка())

Затем, когда вы его оцениваете, вы бы сделали все присваивания от листьев к корню с перезаписью младших точек высшими. Таким образом, в приведенном выше примере точка2 будет назначена случайной точкой (вероятно, плохой). Результат будет умножен на случайную точку, а затем перезапишет исходное назначение, сделанное для точки2, с результатом. Тот же результат будет присвоен точке 1 и, наконец, умножен на случайную точку. Однако, поскольку дальнейших присвоений нет, окончательное значение будет просто отброшено.

Причина, по которой это «более структурировано», заключается в том, что вы должны убедиться, что присваивание никогда не происходит ни на чем, кроме точки. Врачи общей практики, основанные на грамматике или ориентированные на грамматику, особенно хороши в этом. Я отсылаю вас к статье Уигэма (1995), в которой они объясняются:

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

Если вы используете GP, в любом случае вам придется написать некоторые функции для обхода списка для формата, который я описал выше. Я также предлагаю использовать точки и векторные функции, а не x и y, чтобы у вас было меньше терминалов для отслеживания (и ваши деревья программ будут меньше/обрабатываться быстрее). Да, и убедитесь, что функция randompoint() возвращает определенную точку (т. е. убедитесь, что вы оцениваете ее прежде чем поместить ее в хромосому, иначе код выдаст противоречивые результаты — очень плохо, что) . И сделайте диапазон этих возможных точек разумным (т. Е. Не переходите к 100, если вы находитесь в пространстве 10 в квадрате).

У вас есть небольшой путь, но, надеюсь, это укажет вам правильное направление.

person OliasailO    schedule 19.03.2013