У меня проблемы с попыткой разобраться с применением генетических операторов к бинарным деревьям.
Во-первых, у меня есть методы, которые генерируют два типа деревьев для начальной популяции, а именно Grow (дерево переменного размера) и Full (сбалансированное дерево одинаковой формы и размера).
FULL GROW
(*) (*)
(+) (-) (5) (-)
(1)(2) (3)(4) (6) (7)
Класс для каждого дерева выглядит так:
public class Tree<E>{
E element;
Tree<E> left, right;
double rawFit;
int hitRat;
public Tree(E element)
{
this.element=element;
}
public Tree (E element, Tree left, Tree right)
{
this.element = element;
this.left = left;
this.right = right;
}
//MORE
//CODE
}
Теперь у меня возникли проблемы с пониманием того, как реализовать генетические операторы, а именно Mutation и Crossover.
Случайно выбирая дерево из моей начальной популяции, как мне применить эти генетические операторы? Для мутации:
- Мне нужно случайным образом выбрать точку в родительском дереве.
- Удалить все поддерево ниже выбранной точки.
- Создайте новое поддерево той же глубины, что и удаленное поддерево.
- Замените его обратно на исходное родительское дерево и выбранную точку.
Теперь это потомство.
Графическое изображение:
PARENT
(*)
randomly chosen point --> (+) (-)
(1)(2) (3)(4)
OFFSPRING RANDOM SUBTREE
(*)
(NULL) (-) + (*)
(3) (4) (5) (6)
NEW OFFSPRING
(*)
(*) (-)
(5)(6) (3) (4)
Мне также нужно сделать что-то подобное для кроссовера.
Теоретически это кажется простым, но я понятия не имею, как это кодировать (Java). Любая помощь будет оценена по достоинству.
EDIT: метод, который я использовал для создания полного дерева, выглядит следующим образом:
private static final String[] OPERATORS = {"+", "-", "/", "*"};
private static final int MAX_OPERAND = 100;
public static Tree full(int depth) {
if (depth > 1) {
String operator = OPERATORS[random.nextInt(OPERATORS.length)];
return new Tree(operator, full(depth - 1), full(depth - 1));
} else {
return new Tree(random.nextInt(MAX_OPERAND) + 1);
}
}