【问题标题】:Binary Tree Genetic Programming二叉树遗传编程
【发布时间】:2015-10-24 05:07:36
【问题描述】:

我刚刚开始使用遗传编程,但在初始化我的群体时遇到了问题。

我需要一棵树来代表每个候选解决方案 - 问题是,我不熟悉树。

我需要两种初始化方式,即Grow(可变大小的树)和Full(平衡相同形状和大小的树)。

    FULL                        GROW
     (*)                         (*)  
  (+)   (-)                   (5)   (-)
(1)(2) (3)(4)                     (6) (7)

我已经初始化了我的 Tree 类,但是,我不知道如何从这里开始填充树(Full 或 Grow)。

public class Tree{
   Object value;
   Tree left, right;

   public Tree(Object value)
   {
      this.value=value;
   }   

   public Tree (Object value, Tree left, Tree right) 
   {
      this.value = value;
      this.left = left;
      this.right = right;
   } 

   // Getter & setter for the value.
   public Object getValue(){
      return value;}
   public void setValue(Object value){
      this.value = value;}

   // Getters & setters for left & right nodes.
   public Tree getLeft(){
      return left;}
   public Tree getRight(){
      return right;}
   public void setLeft(Tree ln){
      left = ln;}
   public void setRight(Tree rn){
      right = rn;}


}

谁能告诉我如何做到这一点,或者只是朝着正确的方向轻推。

我正在尝试随机填充树直到预定义的深度。

  • 运算符 (+ - / *) 插入除叶节点之外的所有位置。
  • 操作数 (1-100) 仅插入叶节点上

谢谢。

【问题讨论】:

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


    【解决方案1】:

    不是很清楚你想要什么。您是在问如何表示您给出的示例,或者如何根据两种策略之一实现生成随机树的方法?

    您的示例可以用您的 Tree 类表示:

    Tree full = new Tree("*",
            new Tree("+", new Tree(1), new Tree(2)),
            new Tree("-", new Tree(3), new Tree(4)));
    
    Tree grow = new Tree("*",
            new Tree(5),
            new Tree("-", new Tree(6), new Tree(7)));
    

    [编辑]

    您可以使用以下类中的方法随机生成树:

    class TreeGenerator {
        private static final String[] OPERATORS = {"+", "-", "/", "*"};
        private static final int MAX_OPERAND = 100;
    
        private static Random random = new Random();
    
        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);
            }
        }
    
        public static Tree grow(int depth) {
            if (depth > 1 && random.nextBoolean()) {
                String operator = OPERATORS[random.nextInt(OPERATORS.length)];
                return new Tree(operator, grow(depth - 1), grow(depth - 1));
            } else {
                return new Tree(random.nextInt(MAX_OPERAND) + 1);
            }
        }
    
    }
    

    然后,你可以这样做:

    Tree full3 = TreeGenerator.full(3);
    Tree grow4 = TreeGenerator.grow(4);
    

    【讨论】:

    • 您好,抱歉,我已经清楚地编辑了我的原始帖子。我正在尝试使用运算符和操作数随机生成具有预定义深度的树。
    • 谢谢!这正是我想要的!
    【解决方案2】:

    您需要创建两个将元素添加到树的函数。对于 GROW 函数,您可以执行以下操作...

    基本上,您必须根据您决定的标准开始设置叶节点。这不是一个完美的例子,但可以帮助您朝着正确的方向前进。

    我没有运行这个,但这应该演示如何种植一棵树。您可能需要添加功能以使其按您的意愿工作。

    Tree head = new Tree(new Value("*"));
    for ( int x = 0; x < 5; x++){
        head.grow(new Tree(x));
    }
    

    树:

    public class Tree{
       Value value;
       Tree left, right;
    
       public Tree(Value value)
       {
          this.value=value;
       }   
    
       public Tree (Value value, Tree left, Tree right) 
       {
          this.value = value;
          this.left = left;
          this.right = right;
       } 
    
       // Getter & setter for the value.
       public Value getValue(){
          return value;}
       public void setValue(Value value){
          this.value = value;}
    
       // Getters & setters for left & right nodes.
       public Tree getLeft(){
          return left;}
       public Tree getRight(){
          return right;}
       public void setLeft(Tree ln){
          left = ln;}
       public void setRight(Tree rn){
          right = rn;}
    
          public void grow(Tree t){
    
        if(value.compareTo(t) < 0){
          if(right == null){
              setRight(t);
          } else{
              getRight().grow(t);
          }
         else{
          if(left == null){
              setLeft(t);
          } else{
              getLeft().grow(t);
          }
    
        }
    
        public toString(){
           if(left == null && right == null)
               return value.oper;
           else{
               return value.val;
        }
    }
    

    价值:

    公共类价值{ 字符串操作; 整数值

        public value(String str){
             oper = str;
             val = Integer.MIN_VALUE;
        }
    
        public value(Integer x){
            oper = "non";
            val = x;
         }
    
        public int compareTo(Value o){
          if(o.val < val) return -1;
          if(o.val > val) return 1;
          return 0;
        } 
    
    }
    

    【讨论】:

    • 我使用了对象值,因为我的树由运算符 (char) 和操作数 (int) 组成。不知道有没有更好的办法。
    • @Leo 您可能应该创建自己的自定义类,该类同时包含运算符或原语。然后,您可以覆盖 compareTo 并使用 object.equals(t)。上面的代码仍然表明您需要一个函数来附加离开节点。然后,您将创建一个 for 循环,每次迭代都会在树的头部添加一个新节点
    • 非常感谢您的解释。我一定会试一试的。
    【解决方案3】:

    您可以查看 Tiny GP http://cswww.essex.ac.uk/staff/rpoli/TinyGP/ 的实现(由 Ricardo Poli 完成)。但是,该实现需要深入了解 C 编程语言。

    或者,您可以使用具有染色体线性表示的 GP 变体(例如线性 GP、笛卡尔 GP、基因表达编程、多表达编程等)。那些有一个更简单,更容易理解的实现。例如,查看多表达式编程的源代码:http://www.mepx.org/source_code.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-05-02
      • 1970-01-01
      • 1970-01-01
      • 2011-04-06
      • 2015-06-16
      • 2012-01-09
      • 2020-03-29
      相关资源
      最近更新 更多