二叉树上的遗传算子

时间:2015-08-14 11:50:00

标签: java tree binary-tree genetic-algorithm mutation

我在尝试将遗传算子应用于二叉树时遇到了问题。

首先,我有一些方法可以为初始种群生成两种类型的树,即成长(可变大小的树)和完整(平衡相同的形状和大小树)

    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
} 

现在,我正在理解如何实施遗传算子,即突变交叉

从我的初始人群中随机选择一棵树,我该如何应用这些遗传算子呢? 对于突变

  • 我需要在父树中随机选择一个点。
  • 删除所选点下方的整个子树。
  • 生成与已删除子树具有相似深度的新子树。
  • 将其替换回原始父树和选定的点。

这是现在的后代。

图形描述:

                             PARENT
                              (*)            
randomly chosen point -->  (+)   (-)  
                         (1)(2) (3)(4)

       OFFSPRING         RANDOM SUBTREE
         (*)            
    (NULL)  (-)     +        (*) 
          (3) (4)          (5) (6)

     NEW OFFSPRING
          (*)            
      (*)    (-) 
    (5)(6) (3) (4)

我也需要为Crossover做类似的事情。

理论上似乎很容易,但我不知道如何编写这个(Java)。任何帮助将不胜感激。

编辑:我用于生成完整树的方法如下所示:

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);
        }
    }

2 个答案:

答案 0 :(得分:1)

我将尝试简要解释一些步骤。

随机选择父树

中的一个点

这样做的一种方法是在0和树中非叶元素的数量之间选择一个随机数,比如k。随机点将是k元素traversing the tree in order

替换选定点下面的整个子树。

只需将子树设置为新生成的树。像这样:

public class Tree<E> {

    public void mutate() {
        Tree tree = this.getRandomSubtree();
        tree.replace(NEW_RANDOM_TREE);
    }

    public void replace(Tree<E> newTree) {
        if(this.isLeftChild()) this.getParent().setLeft(newTree);
        else                   this.getParent().setRight(newTree);
    }
    ...
}

getRandomSubtree()方法返回树中的随机点 树的getParent()方法返回直接父节点。

请注意,您还必须检查返回的随机子树是根本身的一些情况。

答案 1 :(得分:0)

  1. 随机选择一个点: Select a Node at Random from Unbalanced Binary Tree

  2. 不需要从所选节点中删除子树,只需获取所选子树的深度,并保持对它的引用。 http://www.geeksforgeeks.org/get-level-of-a-node-in-a-binary-tree/

  3. 使用“完整”方法生成一个新的随机子树,其中保存了旧子树的深度,并将此子树分配给旧子树的已保存引用,因此旧子树被垃圾收集器杀死。