Logo
Distributed Genetic Programming Framework
print print

File org.dgpf.gp.automaton.search.ProgramContext.java

Here you can find all the information about the file org.dgpf.gp.automaton.search.ProgramContext.java. You may explore it here or download it onto your local disk.
/*
 * Copyright (c) 2005 Thomas Weise
 * 
 * E-Mail           : tweise@gmx.de
 * Creation Date    : 2005-12-28 11:40:44
 * Original Filename: org.dgpf.automaton.genetics.AutomatonContext.java
 * Version          : 2.2.2
 * Last modification: 2006-06-08
 *                by: Thomas Weise
 * 
 * License          : GNU LESSER GENERAL PUBLIC LICENSE
 *                    Version 2.1, February 1999
 *                    You should have received a copy of this license along
 *                    with this library; if not, write to the Free Software
 *                    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *                    MA 02111-1307, USA or download the license under
 *                    http://www.gnu.org/copyleft/lesser.html.
 *                    
 * Warranty         : This software is provided "as is" without any
 *                    warranty; without even the implied warranty of
 *                    merchantability or fitness for a particular purpose.
 *                    See the Gnu Lesser General Public License for more
 *                    details.
 */

 
package org.dgpf.gp.automaton.search;

import java.util.Random;

import org.dgpf.gp.automaton.base.Conventions;
import org.dgpf.gp.automaton.base.Expression;
import org.dgpf.gp.automaton.base.Instruction;
import org.dgpf.gp.automaton.base.Program;
import org.dgpf.gp.automaton.expressions.Constant;
import org.dgpf.gp.automaton.optimizer.Optimizer;
import org.dgpf.search.api.SearchContext;
import org.dgpf.search.api.utils.WeightedSet;
import org.sfc.events.IEventListener;
import org.sfc.math.stochastic.Randomizer;

/**
 * This basic context provides the methods needed to create, mutate and
 * crossover programs.
 *
 * @author Thomas Weise
 */

public class ProgramContext  extends SearchContext<Program>
  {    
/**
 * The serial version uid.
 */

  private static final long serialVersionUID            = 1;

/**
 * The random set containing the instruction handlers.
 */

  private final WeightedSet<InstructionHandler>          m_instructions;

/**
 * The random set containing the expression handlers.
 */

  private final WeightedSet<ExpressionHandler>          m_expressions;
  

/**
 * The random set containing the wrapable expression handlers.
 */

  private final WeightedSet<WrapableExpressionHandler>  m_wrapables;
/**
 * The random set containing the sequence factories.
 */

  private final WeightedSet<SequenceFactory>            m_sequences;

/**
 * The minimum memory size of a program.
 */

  private final int                                     m_min_mem_size ;
/**
 * Create a new automaton context.
 * @param p_definition  The search definition to use as blueprint for the
 *                      internally stored data.
 * @param p_events      The event listener to be used to propagate
 *                      error events to, if needed.
 */

  protected ProgramContext(final ProgramDefinition  p_definition,
                           final IEventListener     p_events) 
    {
    super(p_definition, p_events);
    
    this.m_expressions    = p_definition.m_expressions;
    this.m_instructions   = p_definition.m_instructions;
    this.m_sequences      = p_definition.m_sequences;
    this.m_wrapables      = p_definition.m_wrapables;
    this.m_min_mem_size   = p_definition.m_min_mem_size;
    }
  
/**
 * Obtain the minimum memory size for programs. If a program is created, it
 * will have at least this memory size (thought maybe <i>uses</i> less
 * memory). Whatsoever, relative memory accesses will be wrapped at at
 * least this size and automata instantiated will have at least this memory
 * available.
 * @return  The minimum memory size.
 */

  public  final int get_min_mem_size  ()
    {
    return this.m_min_mem_size;
    }

/**
 * Create a random expression.
 * @param p_decision    <code>true</code> if and only if the expression
 *                      required is a decisional expression.
 *                      <code>false</code> if it is an arithmetical
 *                      expression.
 * @param p_is_sub_expression <code>true</code>
 * @param p_memory_size   The memory size currently available.
 * @return  The new, random expression.
 */

  public  final Expression  create_expression
                                (final boolean          p_decision,
                                 final boolean          p_is_sub_expression,
                                 final int              p_memory_size)
    {
    WeightedSet<ExpressionHandler>.Session l_hh;
    Random              l_r;
    ExpressionHandler   l_h;
    int                 l_i;

    l_r  = this.get_randomizer();
    l_hh = this.m_expressions.open_session(l_r);    
    l_i  = l_hh.get_remaining();
    
    do
      {
      l_h = l_hh.next();
      } while ( ((--l_i) > 0) &&
              ((!(l_h.can_produce(p_decision)))           ||
                (p_is_sub_expression                       &&
                (l_h instanceof WrapableExpressionHandler) &&
                (l_r.nextDouble() > 0.2d))));

    l_hh.close();
      
    return l_h.create(this, p_decision,
                      Math.max(this.m_min_mem_size, p_memory_size));
    }

/**
 * Create a mutated copy of the specified expression.
 * @param p_source        The source expression.
 * @param p_is_decisional <code>true</code> if and only if the expression
 *                        to mutate is decisional, <code>false</code>
 * @param p_memory_size   The memory size currently available.
 *                        otherwise (a calculative expression).
 * @return  The mutated expression.
 */

  public  final Expression  mutate_expression
                                   (final Expression        p_source,
                                    final boolean           p_is_decisional,
                                    final int               p_memory_size)
    {
    Expression  l_ex;
    int         l_l, l_l2;
    boolean     l_b, l_b2;
    Randomizer  l_r;

    l_r = this.get_randomizer();
    l_b = (p_source instanceof Constant);
    if(l_b) l_l = ((Constant)p_source).get_value();
    else    l_l = 0;
    l_l2 = 0;
    do
      {
      l_ex = p_source.get_handler().mutate(p_source, this,
                    (p_is_decisional ? Conventions.DECISIONAL_EXPR :
                     Conventions.CALCULATIVE_EXPR),
                     Math.max(this.m_min_mem_size, p_memory_size));

      l_b2          = (l_ex instanceof Constant);
      if(l_b2) l_l2 = ((Constant)l_ex).get_value();
      } while(l_b && l_b2 &&
             (p_is_decisional ?
             (Conventions.is_true(l_l2) == Conventions.is_true(l_l))
                              : (l_l2 == l_l)) &&
             (l_r.nextInt(4) <= 0)) ;

    return l_ex;
    }

/**
 * Wrap an expression into another one.
 * @param p_source      The source expression to be wrapped.
 * @param p_is_decisional <code>true</code> if and only if the expression
 *                        to mutate is decisional, <code>false</code>
 *                        otherwise (a calculative expression).
 * @param p_memory_size   The memory size currently available.
 * @return  The wrapped expression.
 */

  public  final Expression  wrap_expression
                                   (final Expression      p_source,
                                    final boolean         p_is_decisional,
                                    final int             p_memory_size)
    {
    WeightedSet<WrapableExpressionHandler>.Session l_whh;
          Expression                  l_r;
          WrapableExpressionHandler   l_wh;
          int                         l_l;

    l_whh = this.m_wrapables.open_session(this.get_randomizer());
    
    for(l_l = l_whh.get_remaining(); l_l > 0; l_l--)
      {
      l_wh = l_whh.next();
      if(l_wh.can_produce(p_is_decisional))
        {
        l_r = l_wh.wrap(this,  p_is_decisional,
                        Math.max(this.m_min_mem_size, p_memory_size),
                        p_source);
        if( (l_r != null) && (l_r != p_source) )
          {
          l_whh.close();
          return l_r;
          }
        }
      }

    l_whh.close();
    return p_source;
    }

/**
 * Create a random instruction.
 * @param p_instruction_count The count of instructions of the program the
 *                            new instruction will be part of.
 * @param p_memory_size   The memory size currently available.
 * @return  The new, random instruction.
 */

  public  final Instruction  create_instruction
                                  (final int         p_instruction_count,
                                   final int         p_memory_size)
    {
    return  this.m_instructions.get(this.get_randomizer())
                               .create(this, p_instruction_count,
                            Math.max(this.m_min_mem_size, p_memory_size));
    }

/**
 * Create a mutated copy of the specified instruction.
 * @param p_source        The source instruction.
 * @param p_instruction_count The count of instructions of the program the
 *                            mutated instruction will be part of.
 * @param p_memory_size   The memory size currently available.
 * @return  The mutated instruction.
 */

  public  final Instruction  mutate_instruction
                                   (final Instruction p_source,
                                    final int         p_instruction_count,
                                    final int         p_memory_size)
    {
    return p_source.get_handler().mutate(p_source, this
                                         p_instruction_count,
                            Math.max(this.m_min_mem_size, p_memory_size));
    }



/**
 * Postprocess a genotype newly created. Whenever the internal creation
 * routines create or derive a new instance of the genotype, it will not
 * be returned directly. Instead, it will be postprocessed first. The post-
 * production may return <code>null</code> if the individual passed in is
 * invalid or should not be investigated any further.
 * @param p_new The newly created or derived individual which now should be
 *              postprocessed.
 * @return  A postprocessed version of <code>p_new</code>, or
 *          <code>null</code>
 */

  @Override
  protected Program postprocess (final Program p_new)
    {
    return super.postprocess(Optimizer.optimize(p_new, this.m_min_mem_size,
                                                this.get_buffer()));
    }


/**
 * Create a mutated copy of the specified instruction.
 * @param p_instruction_count The count of instructions of the program the
 *                            new sequence will be part of.
 * @param p_memory_size   The memory size currently available.
 *                        placed.
 * @param p_position      The position where the new sequence will be
 *                        placed. Use this to align your
 *                        <code>IfJump</code>-instructions.
 * @param p_at_end        <code>true</code> if and only if the code
 *                        sequence is to be inserted at the end.
 * @return  The mutated instruction.
 */

  public  final Instruction[] create_sequence
                                    (final int        p_instruction_count,
                                     final int        p_memory_size,
                                     final int        p_position,
                                     final boolean    p_at_end)
    {
    WeightedSet<SequenceFactory> l_sf;

    l_sf = this.m_sequences;
    if( (l_sf == null) || (l_sf.size() <= 0) ) return null;

    return l_sf.get(this.get_randomizer()).create(
              this, p_instruction_count,
              Math.max(this.m_min_mem_size, p_memory_size), p_position,
              p_at_end);
    }

/**
 * This method is used by <code>create()</code> to obtain new, random
 * program.
 * The new program returned by this method should be created totally
 * randomly, with all its contents based on the internal random number
 * generator.  
 * @return  The new, random program.
 */

  @Override
  protected Program  do_create  ()
    {
          int             l_sc, l_i, l_p, l_ms, l_d;
          Instruction[]   l_ins, l_seg;
    final Randomizer      l_random;

    l_random = this.get_randomizer();
    
    l_sc  = (((int)(l_random.exponential()))+5);
    l_ms  = (this.m_min_mem_size + ((int)(l_random.exponential())));
    l_p   = l_random.nextInt(l_sc + 1);

    l_seg = this.create_sequence(l_sc, l_ms, l_p, l_p >= l_sc);
    if(l_seg != null)
      {
      l_d   = l_seg.length;
      l_sc += l_d;
      }
    else
      {
      l_p = Integer.MAX_VALUE;
      l_d = Integer.MIN_VALUE;
      }

    l_ins = new Instruction[l_sc];

    if(l_seg != null)
      {
      System.arraycopy(l_seg, 0, l_ins, l_p, l_d);

      l_d += l_p;
      }

    for(l_i = (l_sc-1); l_i >= 0; l_i--)
      {
      if( (l_i < l_p) || ( l_i >= l_d) )
        {
        l_ins[l_i] = this.create_instruction(l_sc, l_ms);
        }
      }

    return new Program(l_ins, this.m_min_mem_size);
    }



/**
 * This method is used by <code>mutate()</code> to create a new program by
 * mutating an existing one.
 * The new program will be created basing on the one passed it. It will
 * not be equal to it though - small changes will randomly be performed.
 * 
 * @param p_parent  The parent genotype which should be mutated a bit.
 * @return  <p>
 *          The new, mutated program. Or <code>null</code>,
 *          if no new program could be created successfully.</p><p>
 */

  @Override
  protected Program   do_mutate  (final Program  p_parent)
    {
    return new Program(ProgramMutator.INSTANCE.mutate(
                       Mutator.do_get_code(p_parent), this, 0,
                       Math.max(this.m_min_mem_size,
                       p_parent.get_memory_size())),
                       this.m_min_mem_size);

    }



/**
 * Create a new individual as ancestor of two parent individuals by pairing.
 * @param p_parent_1  The first parent individual.
 * @param p_parent_2  The second parent individual.
 * @param p_context The automaton context to be used for this operation.
 * @return  The new child individual, create by crossover.
 *
 */

  public  final Program crossover(final Program                 p_parent_1,
                                  final Program                 p_parent_2,
                                  final SearchContext<Program>  p_context)
    {
    return new Program(
            Crossover.crossover(Mutator.do_get_code(p_parent_1),
                                Mutator.do_get_code(p_parent_2),
                                this.get_randomizer()),
                                this.m_min_mem_size);
    }


/**
 * Create a random memory address.
 * @param p_memory_size The current memory size.
 * @param p_random      The randomizer.
 * @return  A new, random address.
 */

  public  static  final int   random_address  (final int        p_memory_size,
                                               final Randomizer p_random)
    {
    if((p_memory_size <= 0) ||
       (p_random.nextDouble() < (1.0d/(p_memory_size+1))))
      {
      return p_random.nextInt(p_memory_size + 1);
      }
    return p_random.nextInt(p_memory_size);
    }
  }

File Information:

file name:ProgramContext.java
package:org.dgpf.gp.automaton.search
qualified name:org.dgpf.gp.automaton.search.ProgramContext.java
file type:Java Source File
download location:download http://dgpf.sourceforge.net/source/org/dgpf/gp/automaton/search/ProgramContext.java
size:15.296 KB (15664 B)
uploaded: 2015-07-22 04:10:55 GMT+0000
last update: 2006-06-26 12:25:46 GMT+0000
last access: 2017-11-19 03:08:16 GMT+0000

statistics online since 2006-01-02.   RSS Feed
Contact us by sending an email to tweise@gmx.de to receive further information, to report errors, or to join our project.
All content on this site (http://dgpf.sourceforge.net/) is LGPL-licensed.
http://dgpf.sourceforge.net/scripts/source/source.php last modified at 2015-07-22 04:10:53 GMT+0000 served at 2017-11-19 03:08:16 GMT+0000.
Valid CSS Valid XHTML 1.1
Valid RSS SourceForge.net Logo