Logo
Distributed Genetic Programming Framework
print print

File org.dgpf.gp.vm.base.VMContext.java

Here you can find all the information about the file org.dgpf.gp.vm.base.VMContext.java. You may explore it here or download it onto your local disk.
/*
 * Copyright (c) 2006 Thomas Weise
 * 
 * E-Mail           : tweise@gmx.de
 * Creation Date    : 2006-06-26 15:02:02
 * Original Filename: org.dgpf.gp.vm.base.VMContext.java
 * Version          : 1.0.0
 * Last modification: 2006-06-26
 *                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.vm.base;

import org.dgpf.gp.vm.mutation.MutationInfo;
import org.dgpf.gp.vm.mutation.ProgramCrossover;
import org.dgpf.gp.vm.mutation.ProgramMutator;
import org.dgpf.gp.vm.optimization.CodeOptimizer;
import org.dgpf.search.api.SearchContext;
import org.sfc.events.IEventListener;
import org.sfc.math.stochastic.Randomizer;

/**
 * The context to be used for evolution of vm programs.
 *
 * @author Thomas Weise
 */

public abstract class VMContext extends     SearchContext<Program>
                                implements  IVMInformation
  {
/**
 * The serial version uid.
 */

  private static final long serialVersionUID = 1;
/**
 * The first free vm memory slot.
 */

                VMMemory        m_mem   ;
/**
 * The first free vm frame slot.
 */

                VMFrame         m_frame ;
/**
 * The maximum memory frame size. 
 */

  private       int             m_max_mem_size  ;
/**
 * The maximum count of execution frames that can be granted to an
 * automaton during the simulation process.
 */

                int             m_max_frame_count ;
/**
 * The internal mutation info record.
 */

  private final MutationInfo    m_mut_info;
                

/**
 * The instruction set to be used by the virtual machine programs.
 * @see #get_instruction_set()
 */

  private       InstructionSet  m_instruction_set ;
/**
 * The minimum count of procedures. You may set this count to some value
 * greater than one if needing asynchronous io.
 * @see #get_min_proc_count()
 */

  private       int             m_min_proc_count  ;
/**
 * Is relative addressing possible?
 * @see #can_relative()
 */

  private       boolean         m_can_relative    ;
  
/**
 * Create a vm 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, if needed.
 */

  public    VMContext (final VMDefinition   p_definition,
                       final IEventListener p_events) 
    {
    super(p_definition, p_events);    
        
    VMFrame  l_vf, l_v3;
    int      l_i;
    
    l_vf = null;
    for(l_i = (VMUtils.DEFAULT_MAX_EXEC_COUNT/3); l_i >= 0; l_i--) 
      {      
      l_v3        = new VMFrame(this);
      l_v3.m_prev = l_vf;
      l_vf        = l_v3;
      }
    
    this.m_mut_info = new MutationInfo();
    }
  
  
/**
 * This method is used by <code>create()</code> to obtain new, random
 * instances of the genotype.
 * The new instance returned by this method should be created totally
 * randomly, with all its contents based on the internal random number
 * generator. No postprocessing must be done here, all will be performed
 * in the <code>create()</code>-routine. 
 * @return  The new, random instance of the genotype.
 */

  @Override
  protected final Program do_create  ()
    {
    return new Program(ProgramMutator.create(thisthis.m_mut_info));
    }
  
/**
 * This method is used by <code>mutate()</code> to create a new instance of
 * the genotype by mutating an existing one.
 * The new instance will be created basing on the one passed it. It will
 * not be equal to it though - small changes will randomly be performed.
 * No postprocessing must be done here, all will be performed in the
 * <code>mutate()</code>-routine.
 * 
 * @param p_parent  The parent genotype which should be mutated a bit.
 * @return  <p>
 *          The new, mutated instance of the genotype. Or <code>null</code>,
 *          if no new instance could be created successfully.</p><p>
 *          <i>Warning:</i> This method currently always returns
 *          <code>null</code>, you must override it in order to provide a
 *          proper mutation operator.</p>.
 */

  @Override
  protected final Program do_mutate  (final Program p_parent)
    {
    Instruction[][] l_i, l_j;
    
    l_i = p_parent.m_code;
    l_j = ProgramMutator.mutate(thisthis.m_mut_info, l_i);
    
    return (((l_i != l_j) && (l_j != null)) ? new Program(l_j) : null);
    }
  


/**
 * Create a new individual by merging two other individuals. This method
 * instanciates the genotype by emulating the biological crossover
 * operation.
 * No postprocessing must be done here, all will be performed in the
 * <code>crossover()</code>-routine.
 * 
 * @param p_parent_1    The first parent individual.
 * @param p_parent_2    The second parent individual.
 * 
 * @return  <p>The new genotype instance (individual) which is a
 *          combination of both parents, or <code>null</code>, if no new
 *          instance could be created successfully.</p><p>
 *          <i>Warning:</i> This method currently always returns
 *          <code>null</code>, you must override it in order to provide a
 *          proper crossover operator.</p>.
 */

  @Override
  protected Program do_crossover (final Program p_parent_1,
                                  final Program p_parent_2)
    {    
    Instruction[][] l_i1, l_i2, l_i3;
    
    l_i1 = p_parent_1.m_code;
    l_i2 = p_parent_2.m_code;
    l_i3 = ProgramCrossover.crossover(l_i1, l_i2, this);
    
    if((l_i3 != null) && (l_i3 != l_i2) && (l_i3 != l_i1))
      {
      return new Program(l_i3);
      }
    
    return null;
    }
  
/**
 * Allocate a new vm memory frame.
 * @return  The new memory frame.
 */

  final VMMemory  allocate_mem  ()
    {
    VMMemory  l_vm;
    
    l_vm = this.m_mem;
    if(l_vm == null)
      {
      l_vm = new VMMemory(this.m_max_mem_size);
      return l_vm;
      }
    
    this.m_mem = l_vm.m_next;
    l_vm.m_next = null;    
    l_vm.m_size = 0;
    
    return l_vm;
    }
  

/**
 * Copy a virtual machine memory frame.
 * @param p_memory  The memory to be copied.
 * @return  A perfect copy of that memory.
 */

  protected final VMMemory  copy_mem(final VMMemory p_memory)
    {
    VMMemory l_m;
    int      l_i;
    
    l_m = this.allocate_mem();
    l_i = p_memory.m_size;
    
    if(l_i > 0)
      {
      l_m.m_size = l_i;
      System.arraycopy(p_memory.m_data, 0, l_m.m_data, 0, l_i);
      }
    
    return l_m;
    }
  
/**
 * Dispose a memory frame.
 * @param p_mem The frame to be disposed.
 */

  public  final void  dispose_mem(final VMMemory p_mem)
    {
    if(p_mem != null)
      {
      p_mem.m_next = this.m_mem;
      this.m_mem   = p_mem;
      }
    }
  
/**
 * Allocate a new vm execution frame.
 * @return  The new execution frame.
 */

  final VMFrame  allocate_frame  ()
    {
    VMFrame  l_vm;
    
    l_vm = this.m_frame;
    if(l_vm == null)
      {
      l_vm = new VMFrame(this);
      return l_vm;
      }
    
    this.m_frame = l_vm.m_prev;
    l_vm.m_stack = this.allocate_mem();
    l_vm.clear();    
    return l_vm;
    }
  
/**
 * Dispose an execution frame.
 * @param p_frame The frame to be disposed.
 */

  final void  dispose_frame(final VMFrame p_frame)
    {    
    dispose_mem(p_frame.m_parameters);
    dispose_mem(p_frame.m_stack);
    p_frame.m_parameters = null;
    p_frame.m_stack      = null;
    p_frame.m_prev       = this.m_frame;
    p_frame.m_code       = null;
    this.m_frame         = p_frame;
    }
  
  

/**
 * Assign this virtual machine context to the specified object.
 * @param p_data  The object to assign to.
 */

  @Override
  public void  assign  (final Object p_data)
    {
    VMDefinition l_def;
    VMContext    l_ctx;
    boolean      l_rm, l_r, l_q;
    int          l_i, l_j;
    VMMemory     l_vm, l_v2;
    
    super.assign(p_data);
    
    l_rm = false;
    l_r  = false;
    l_q  = ((this.m_max_frame_count > 0) || (this.m_max_mem_size > 0));
    
    if(p_data instanceof VMDefinition)
      {
      l_def = ((VMDefinition)p_data);
      
      l_j   = l_def.get_max_mem_size();
      if(l_j != this.m_max_mem_size)
        {
        this.m_max_mem_size = l_j;
        l_rm = true;
        }
      
      l_i = l_def.get_max_frame_count();
      if(l_i != this.m_max_frame_count)
        {
        l_r = true;
        this.m_max_frame_count = l_i;
        }
      
      this.set_instruction_set(l_def.get_instruction_set());
      this.set_min_proc_count(l_def.get_min_proc_count());
      this.m_can_relative = l_def.can_relative();
      }
    else if(p_data instanceof VMContext)
      {
      l_ctx = ((VMContext)p_data);
      
      l_j   = l_ctx.get_max_mem_size();
      if(l_j != this.m_max_mem_size)
        {
        this.m_max_mem_size = l_j;
        l_rm = true;
        }
      
      l_i = l_ctx.get_max_frame_count();
      if(l_i != this.m_max_frame_count)
        {
        l_r = true;
        this.m_max_frame_count = l_i;
        }
      
      this.set_instruction_set(l_ctx.m_instruction_set);
      this.set_min_proc_count(l_ctx.m_min_proc_count);
      this.m_can_relative = l_ctx.m_can_relative;
      }
    else l_j = 0;
    
    if(l_q && (l_r || l_rm)) this.reset_caches();
    
    if(l_rm)
      {    
      l_vm = null;
      for(l_i = (VMUtils.DEFAULT_MAX_EXEC_COUNT/3); l_i >= 0; l_i--) 
        {
        l_v2        = new VMMemory(l_j);
        l_v2.m_next = l_vm;
        l_vm        = l_v2;
        }
      }
    }
  

/**
 * Obtain the maximum memory frame size.
 * @return The maximum memory frame size.
 */

  public  final int get_max_mem_size  ()
    {
    return this.m_max_mem_size;
    }
  
  
/**
 * Obtain the maximum count of execution frames that can be granted during
 * the simulation process.
 * @return The maximum count of execution frames that can be granted during
 *         the simulation process.
 */

  public  final int get_max_frame_count  ()
    {
    return this.m_max_frame_count;
    }
    
/**
 * This method needs to be called whenever the internal caches (virtual
 * machines for example) need to be resetted.
 */

  protected void  reset_caches()
    {
    //
    }
  
  
/**
 * Obtain the instruction set to be used form virtual machines.
 * @return The instruction set to be used form virtual machines.
 */

  public  final InstructionSet  get_instruction_set()
    {
    return this.m_instruction_set;
    }

/**
 * Set the instruction set to be used form virtual machines.
 * @param p_set The instruction set to be used form virtual machines.
 */

  public    final void  set_instruction_set (final InstructionSet p_set)
    {
    if( (p_set != null) && (p_set.size() > 0) )
      {
      this.m_instruction_set = p_set;
      }
    }
  

/**
 * Obtain the minimum count of procedures. This count might be a value
 * greater than one if needing asynchronous io.
 * @return The minimum count of procedures. This count might be a value
 *         greater than one if needing asynchronous io.
 */

  public  final int get_min_proc_count  ()
    {
    return this.m_min_proc_count;
    }
  
/**
 * The minimum count of procedures. You may set this count to some value
 * greater than one if needing asynchronous io.
 * @param p_min_proc_count  The new minimum procedure count. You may set
 *                          this count to some value greater than one if
 *                          needing asynchronous io.
 */

  public   void  set_min_proc_count  (final int p_min_proc_count)
    {
    if(p_min_proc_count >= 1) this.m_min_proc_count = p_min_proc_count;
    }
  
  
/**
 * 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 final Program postprocess (final Program p_new)
    {
    Instruction[][] l_i, l_j;

    l_i = p_new.m_code;
    l_j = CodeOptimizer.optimize(l_i, this);
    
    return super.postprocess((l_i == l_j) ? p_new : new Program(l_j));
    }
  
/**
 * Prepare the context for the given individual. This method is called
 * before any simulation concerning the given individual is done. It
 * provides the context the opportunity to prepare some information or
 * other data. This function also invokes the sanity checking of the
 * fitness functions.
 * @param p_individual  The individual to prepare for.
 * @return  <code>true</code> if everything is ok and we cal begin the
 *          simulations, <code>false/<code> if something is wrong and no
 *          simulations should be performed.
 * @see #get_current()
 * @see #end_individual()
 */

  @Override
  protected boolean begin_individual(final Program  p_individual)
    {
    boolean l_b;
    
    l_b = super.begin_individual(p_individual);
    
    return (l_b && (p_individual.m_code.length >= this.m_min_proc_count));
    }


/**
 * Mutate an address.
 * @param p_old      The old address.
 * @param p_info     The mutation info.
 * @return  A new address different from the old one.
 */

  public  final int mutate_address  (final int          p_old,
                                     final MutationInfo p_info)
    {    
    int         l_mms, l_maa, l_mia, l_a;
    Randomizer  l_r;
    double      l_d;
    
    l_mms = this.m_max_mem_size;
    l_r   = this.get_randomizer();
    
    l_maa = p_info.get_highest_addr();
    l_mia = p_info.get_lowest_addr();
    
    l_maa -= l_mia; 
    if(l_maa < 1) l_maa = 1;
    else          l_maa++;
    
    do
      {      
      l_d = l_r.nextDouble();
      l_d = (l_d*l_d*l_d);
      
      if(l_r.nextInt(4) >= 1)
        {
        l_a = ((int)((l_maa+1)*l_d));
        }
      else
        {
        l_a = ((-((int)((-l_mia)*l_d)))-1);
        }      
      } while( (l_a == p_old) || (l_a >= l_mms) || (l_a < (-l_mms-1)));
    
    return l_a;
    }


/**
 * Create a boolean value determining if a memory access is relative or
 * not.
 * @return <code>true</code> if and only if a memory access is relative.
 */

  public  final boolean create_relative ()
    {
    return (this.m_can_relative && (this.get_randomizer().nextInt(5) < 1));
    }


/**
 * Mutate an address.
 * @param p_info     The mutation info.
 * @return  A new address different from the old one.
 */

  public  final int random_address  (final MutationInfo p_info)
    {    
    return this.mutate_address(Integer.MAX_VALUE, p_info);
    }
  
/**
 * Check whether this context supports the relative addressing mode or not.
 * @return  <code>true</code> if and only relative addressing (and thus,
 *          turing completeness,) is supported, <code>false</code> if only
 *          absolute addresses are available.
 */

  public  final boolean can_relative  ()
    {
    return this.m_can_relative;
    }
  }

File Information:

file name:VMContext.java
package:org.dgpf.gp.vm.base
qualified name:org.dgpf.gp.vm.base.VMContext.java
file type:Java Source File
download location:download http://dgpf.sourceforge.net/source/org/dgpf/gp/vm/base/VMContext.java
size:16.056 KB (16442 B)
uploaded: 2015-07-22 04:10:56 GMT+0000
last update: 2006-08-21 06:32:38 GMT+0000
last access: 2017-11-23 05:32:53 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-23 05:32:53 GMT+0000.
Valid CSS Valid XHTML 1.1
Valid RSS SourceForge.net Logo