Logo
Distributed Genetic Programming Framework
print print

File org.dgpf.search.api.SearchEngine.java

Here you can find all the information about the file org.dgpf.search.api.SearchEngine.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-03-30 13:17:28
 * Original Filename: org.dgpf.search.api.SearchEngine.java
 * Version          : 2.1.11
 * Last modification: 2006-07-21
 *                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.search.api;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;

import org.dgpf.search.api.HaltParameters.HaltType;
import org.dgpf.search.api.events.SearchResetEvent;
import org.dgpf.search.api.events.SearchUpdateEvent;
import org.sfc.events.EventPropagator;
import org.sfc.io.IO;
import org.sfc.math.stochastic.Randomizer;
import org.sfc.parallel.CompoundActivity;
import org.sfc.parallel.SfcThreadGroup;
import org.sfc.utils.Typesafe;


/**
 * The class search engine defines basic behavior for all applications
 * that are able to search (multi-objectively) using probabilistic measures.
 *
 * @param <Genotype>    The sort of genotype used to represent individuals.
 *                      This must be a serializable type.
 *
 * @author Thomas Weise
 */

public abstract class   SearchEngine<Genotype extends Serializable>
                extends CompoundActivity
  {
/**
 * The search parameters guiding the search.
 */

  private         SearchParameters<Genotype>    m_parameters  ;
/**
 * The search state accessor bag.
 */

  private         SearchStateBag<Genotype>      m_state_bag   ;
/**
 * The search state.
 */

  private         SearchState<Genotype>         m_state       ;  
/**
 * The internal randomizer.
 */

  private final   Randomizer                    m_random  ;
/**
 * If this parameter is <code>true</code>, the whole virtual machine should
 * shut down when the search terminates.
 * @see #get_exit()
 * @see #set_exit(boolean)
 */

  private           boolean                     m_exit    ;
/**
 * Set by the <code>reset()</code> method.
 * @see #reset()
 */

  private volatile  boolean                     m_reset   ;
/**
 * The thread performing the update work.
 */

  private           UpdateThread                m_ut  ;
/**
 * The non-dominated list.
 */

  private           NonDominatedList<Genotype>  m_ndl ;
/**
 * The non-dominated list of the current search run.
 */

  private           NonDominatedList<Genotype>  m_rndl;
/**
 * <code>true</code> if and only if a garbage collection should be
 * performed after each update, <code>false</code> otherwise.
 * @see #set_use_gc(boolean)
 * @see #get_use_gc()
 */

  private volatile  boolean                     m_gc  ;
/**
 * <code>true</code> if and only if the events of thrown by this engine
 * should be serializable, <code>false</code> otherwise.
 * @see #set_events_serializable(boolean)
 * @see #are_events_serializable()
 */

  private volatile  boolean                     m_events_serializable;
  
/**
 * Create a new instance of the search engine without providing additional
 * information or parameters. This method will be used when loading a
 * snapshot mostly.
 */

  protected SearchEngine  ()
    {
    super(null, new SearchThreadGroup("Search Engine"));
    this.m_random = new Randomizer();
    }
  
/**
 * Create a new instance of the search engine.
 * @param p_parameters  The parameters object guiding the search process.
 * @param p_ndl_size    The size of the non-dominated list. Set this
 *                      to <code>-1</code> for don't care.
 */

  protected SearchEngine  (final SearchParameters<Genotype> p_parameters,
                           final int                        p_ndl_size)
    {
    this();
       
    this.m_parameters = p_parameters;
    this.m_state_bag  = this.create_state();
    this.m_state      = this.m_state_bag.m_state;
    this.m_ndl        = new NonDominatedList<Genotype>(p_ndl_size,
                              p_parameters.get_fitness_function_count(),
                              p_parameters.get_comparator());
    this.m_rndl       = new NonDominatedList<Genotype>(p_ndl_size,
                              p_parameters.get_fitness_function_count(),
                              p_parameters.get_comparator());
    
    this.m_state.assign(p_parameters);    
    
    this.initialize(false);
    }
  
  
/**
 * If this parameter is <code>true</code>, the whole virtual machine should
 * shut down when the search terminates.
 * @return  <code>true</code> if and only if the virtual machine, i.e. the
 *          whole process, should terminate when the search terminates.
 */

  public  final boolean get_exit  ()
    {
    return this.m_exit;
    }
  
/**
 * If set to <code>true</code>, the whole virtual machine should shut down
 * when the search terminates.
 * @param p_exit  <code>true</code> if and only if the virtual machine, i.e.
 *                the whole process, should terminate when the search
 *                terminates.
 */

  public  final void  set_exit  (final boolean p_exit)
    {
    this.m_exit = p_exit;
    }
  
/**
 * If this parameter is <code>true</code>, a garbage collection should be
 * triggered after each update.
 * @return  <code>true</code> if and only if a garbage collection should be
 *          triggered after each update, <code>false</code> if no garbage
 *          collection is needed.
 * @see #set_use_gc(boolean)
 */

  public  final boolean get_use_gc  ()
    {
    return this.m_gc;
    }
  
/**
 * If set to <code>true</code>, a garbage collection should be
 * triggered after each update. This should only be done if we have
 * simulations with high memory usage / involving a lot of allocations and
 * dereferencations.
 * @param p_gc <code>true</code> if and only if a garbage collection should
 *             be triggered after each update, <code>false</code> if no
 *             garbage collection is needed.
 */

  public  final void  set_use_gc  (final boolean p_gc)
    {
    this.m_gc = p_gc;
    }
  
/**
 * Obtain the randomizer used by this search engine during its update-
 * cycles.
 * @return The randomizer used by this search engine during its update-
 *         cycles.
 */

  protected final Randomizer  get_randomizer()
    {
    return this.m_random;
    }
  
/**
 * This method is used to create the search state (and its accessor bag) to
 * be used by this search engine.
 * @return  A new search state (and its accessor bag).
 */

  protected SearchStateBag<Genotype>  create_state  ()
    {
    return new SearchStateBag<Genotype>(this.m_parameters
                                            .get_fitness_function_count());
    }
  
/**
 * Obtain the state accessor bag allowing you to modify the state of the
 * search.
 * @return The state accessor bag allowing you to modify the state of the
 *         search.
 */

  protected final SearchStateBag<Genotype>  get_state_bag ()
    {
    return this.m_state_bag;
    }
  
/**
 * Obtain the state information of the search.
 * @return The state information of the search.
 */

  protected final SearchState<Genotype>     get_state ()
    {
    return this.m_state;
    }
  
/**
 * Obtain the dynamic search control data.
 * @return The dynamic search control data.
 */

  public  final SearchParameters<Genotype>  get_parameters  ()
    {
    return this.m_parameters;
    }
  
/**
 * This method is called to initialize the search engine. You must all
 * initialization code here.
 * @param p_deserialized  <code>true</code> if and only if this
 *                        initialization was called due to an
 *                        deserialization process, <code>false</code> if it
 *                        is the normal initialization in the constructor.
 */

  protected void  initialize  (final boolean p_deserialized)
    {
    SearchEngine<Serializable>  l_se;
    l_se = Typesafe.cast(this);
    
    this.m_ut = new UpdateThread(l_se);
    
    if(this.m_ndl == null)
      {
      this.m_ndl = new NonDominatedList<Genotype>(-1,
          this.m_parameters.get_fitness_function_count(),
          this.m_parameters.get_comparator());                                        
      }
    if(this.m_rndl == null)
      {
      this.m_rndl = new NonDominatedList<Genotype>(-1,
          this.m_parameters.get_fitness_function_count(),
          this.m_parameters.get_comparator());                                        
      }
    }
  
/**
 * This method must be called by <code>do_start()</code> when all other
 * initialization/startup work is done an the updating can begin.
 */

  protected final void  begin_work()
    {
    if(this.is_running() && (!(this.m_ut.is_running())))
      {
      this.m_ut.start();
      }
    }
  
/**
 * This method aborts the activity. It is guaranteed to be called only once
 * for aborting and once for shutdown.
 * @see #abort()
 * @see #shutdown()
 */

  @Override
  protected void  do_abort  ()
    {
    super.do_abort();
    this.m_ut.abort();
    }
  

/**
 * Wait for this object.
 */

  @Override
  public  void  wait_for  ()
    {    
    this.m_ut.wait_for();
    super.wait_for();
    }
  
/**
 * Store a snapshot into an object output stream.
 * @param p_oos The object output stream to write to.
 * @throws  IOException If io fails.
 */

  protected void  do_write_snapshot (final ObjectOutputStream p_oos)
        throws IOException
    {
  //  
    }
  
/**
 * Read a snapshot from an object input stream.
 * @param p_ois  The object input stream to read from.
 * @throws  IOException             If io goes terribly wrong.
 * @throws  ClassNotFoundException  If a vital class could not be found.
 */

  protected void  do_read_snapshot  (final ObjectInputStream  p_ois)
        throws IOException, ClassNotFoundException
    {
    //
    }
  
/**
 * Store a snapshot into an object output stream.
 * @param p_oos The object output stream to write to.
 * @throws  IOException If io fails.
 */

  public synchronized final void write_snapshot
                                    (final ObjectOutputStream p_oos)
        throws IOException
    {    
    try
      {
      p_oos.writeUnshared(this.m_parameters);
      p_oos.writeUnshared(this.m_state_bag);      
      p_oos.writeUnshared(this.m_ndl);
      p_oos.writeUnshared(this.m_rndl);
      
      this.do_write_snapshot(p_oos);
      }
    finally
      {
      p_oos.close();
      }
    }
  
/**
 * Read a snapshot from an object input stream.
 * @param p_ois  The object input stream to read from.
 * @throws  IOException             If io goes terribly wrong.
 * @throws  ClassNotFoundException  If a vital class could not be found.
 */

  public synchronized final void read_snapshot(final ObjectInputStream p_ois)
        throws IOException, ClassNotFoundException
    {
    this.abort_and_wait();
    
    try
      {
      this.m_parameters = Typesafe.cast(p_ois.readUnshared());
      this.m_state_bag  = Typesafe.cast(p_ois.readUnshared());
      this.m_state      = this.m_state_bag.m_state;
      this.m_ndl        = Typesafe.cast(p_ois.readUnshared());
      this.m_rndl       = Typesafe.cast(p_ois.readUnshared());
      
      this.do_read_snapshot(p_ois);
      }
    finally
      {
      p_ois.close();
      }
    
    this.initialize(true);
    }
  
/**
 * Store a snapshot into an output destination described by an object.
 * @param p_dest  The output destination.
 * @throws  IOException If io fails.
 */

  public  final void  write_snapshot  (final Object p_dest)
                                                        throws IOException
    {
    OutputStream        l_os;
    ObjectOutputStream  l_oos;
    
    l_os = IO.get_output_stream(p_dest);
    if(l_os == null) throw new IOException();
    
    try
      {
      l_oos = new ObjectOutputStream(l_os);
      try
        {
        this.write_snapshot(l_oos);
        }
      finally
        {
        l_oos.close();
        }
      }
    finally
      {
      l_os.close();
      }
    }
  
/**
 * Read a snapshot from an input stream described by an object.
 * @param p_source  The input source.
 * @throws  IOException             If io goes terribly wrong.
 * @throws  ClassNotFoundException  If a vital class could not be found.
 */

  public  final void  read_snapshot (final Object p_source)
                               throws IOException, ClassNotFoundException
    {
    InputStream       l_is;
    ObjectInputStream l_ois;
    
    l_is = IO.get_input_stream(p_source);
    if(l_is == null) throw new IOException();
    
    try
      {
      l_ois = new ObjectInputStream(l_is);
      try
        {
        this.read_snapshot(l_ois);
        }
      finally
        {
        l_ois.close();
        }
      }
    finally
      {
      l_is.close();
      }
    }
  
  
/**
 * The internal update caller.
 * @return  <code>true</code> if and only if the search should continue,
 *          <code>false</code> otherwise.
 * @see #update()
 */

  final boolean do_update()
    {   
    SearchState<Genotype> l_s;
    
    l_s = this.m_state;
    l_s.m_improvement   = -1;
    l_s.m_improvement_2 = -1;
    return this.update();
    }
  
/**
 * This method is called whenever the search is resetted.
 * @see #reset()
 * @see org.dgpf.search.api.events.SearchResetEvent
 */

  protected void  perform_reset ()
    {        
    this.m_reset = false;
    this.m_state.reset_update_level();
    this.m_parameters.reset();
    this.m_rndl.flush();
    this.get_event_propagator().receive(new SearchResetEvent(this));
    }
  
/**
 * Perform an update of the parameters and state. When overriding this
 * method, make sure to update the state's statistics before calling this
 * method.
 * @return  <code>true</code> if and only if the search should continue,
 *          <code>false</code> otherwise.
 * @see SearchStateBag#check_best(Individual, int)
 * @see SearchStateBag#check_best(Individual, IndividualComparator)
 * @see #add_tasks(int)
 */

  protected boolean  update  ()
    {
    SearchParameters<Genotype> l_sp;
    SearchState<Genotype>      l_ss, l_d;
    HaltType                   l_ht;
    EventPropagator            l_ep;
    
    l_sp = this.m_parameters;
    l_ss = this.m_state;

    l_ss.update();
    l_ep = this.get_event_propagator();
    
// this is needed to ensure that the search state is always synchronized
// during a possible storage operation.
    if(this.m_events_serializable) l_d = Typesafe.cast(l_ss.clone());
    else                           l_d = l_ss;
    l_ep.receive(new SearchUpdateEvent<Genotype>(this, l_d));
      
    
    if(l_sp.adapt(l_ss) || this.m_reset)
      {
      this.m_reset = false;
      this.perform_reset();
      }
    else
      {
      l_ss.inc_update_level();
      }
    
    l_ht = l_sp.get_halt_parameters().should_halt(l_ss);
    if(l_ht != HaltParameters.GO_ON)
      {
      if(l_ht != HaltParameters.SHUTDOWN) this.shutdown();
      else                                this.abort();
      return false;
      }
       
    l_ss.assign(l_sp);
    this.m_ndl.set_comparator(l_sp.get_comparator());
    this.m_rndl.set_comparator(l_sp.get_comparator());
    
    if(this.m_gc) do_gc();
    
    return true;
    }
  
/**
 * Perform the garbage collection.
 */

  private static  final void  do_gc()
    {    
    System.runFinalization();
    System.gc();
    System.runFinalization();
    System.gc();
    System.runFinalization();
    }
  
/**
 * This method is called after the search engine has terminated. It will be
 * called by <code>defer_on_close()</code> after all the engine's activities
 * have been finished. This method must not be called in any other way than
 * that.
 */

  @Override
  protected final void  after_termination  ()
    {
    super.after_termination();
    
    if(this.m_exit)
      {
      this.get_event_propagator().close_all_listeners();
      System.exit(0);
      }
    
    do_gc();
    }
  
  
/**
 * The human readable name of the search engine.
 * @return The human readable name of the search engine.
 */

  @Override
  public  String  toString  ()
    {
    return "Search Engine";
    }
  
/**
 * Inform the search engine that one task has been performed successfully.
 * This method must be called by the <code>update()</code> method to update
 * the state's task count information.
 * @param p_tc  The task count to be added.
 */

  protected final void  add_tasks (final int p_tc)
    {
    this.m_state.m_task_count += p_tc;
    }
  
/**
 * Set the current update level back to zero (in the next update).
 */

  public  final void  reset ()
    {
    this.m_reset = true;
    }
  
/**
 * Startup the activity. This method will be called by <code>start()</code>.
 * @see #start()
 */

  @Override
  protected   void  do_start  ()
    {
    super.do_start();
    this.m_state.start();
    }
  

/**
 * Obtain the internal thread group.
 * @return  The internal thread group.
 */

  final SfcThreadGroup  do_get_thread_group()
    {
    return this.get_thread_group();
    }
  
/**
 * Obtain the list of non-dominated individuals encountered during the
 * evolution.
 * @return The list (read-only) of non-dominated individuals encountered
 *         during the evolution.
 */

  public  final NonDominatedList<Genotype>  get_non_dominated()
    {
    return this.m_ndl;
    }  
  
/**
 * Obtain the list of non-dominated individuals encountered during the
 * current run of the evolution. (Since the last reset)
 * @return The list of non-dominated individuals encountered during the
 *         current run of the evolution. (Since the last reset)
 */

  public  final NonDominatedList<Genotype>  get_rel_non_dominated()
    {
    return this.m_rndl;
    }
  
/**
 * Notify the search engine that a non-dominated individual has been found.
 * If it is non-dominated by all individuals ever found, it is stored
 * inside the non-dominated list.
 * @param p_individual  The non-dominated individual found.
 */

  protected final void  notify_nondominated 
                          (final Individual<Genotype> p_individual)
    {
    if(this.m_rndl.check_in(p_individual))
      {
      this.m_ndl.check_in(p_individual);
      this.m_state_bag.check_best(p_individual,
                                  this.m_parameters.get_comparator());
      }
    }

/**
 * Check whether a new best individual has been found.
 * @param p_individual  The new, possible non-dominated individual found.
 * @return  <code>true</code> if and only if the new individual was really
 *          non-dominated. 
 */

  public  synchronized  final boolean check_best 
            (final Individual<Genotype> p_individual)
    {
    if(this.m_ndl.check_in(p_individual))
      {
      this.m_state_bag.check_best(p_individual,
                                this.m_parameters.get_comparator());
      this.m_rndl.check_in(p_individual);
      return true;
      }
    return false;
    }
  
/**
 * Obtain the event propagator suitable for this activity.
 * @return The event propagator suitable for this activity.
 */

  final EventPropagator do_get_event_propagator  ()
    {
    return this.get_event_propagator();
    }

/**
 * Query if the events thrown by this search engine should be
 * serializable or not. Creating serializable events consumes additional
 * resources (processing time, memory). Events not created in serializable
 * mode however cannot be serialized more than one time to a single stream.
 * @return  <code>true</code> if and only if the events of thrown by this
 *          engine should be serializable, <code>false</code> otherwise.
 * @see #set_events_serializable(boolean)
 */

  public  final boolean are_events_serializable()
    {
    return this.m_events_serializable;
    }
  
/**
 * Determine if the events thrown by this search engine should be
 * serializable or not. Creating serializable events consumes additional
 * resources (processing time, memory). Events not created in serializable
 * mode however cannot be serialized more than one time to a single stream.
 * @param p_ser <code>true</code> if and only if the events of thrown by this
 *              engine should be serializable, <code>false</code> otherwise.
 * @see #are_events_serializable()
 */

  public  final void  set_events_serializable (final boolean p_ser)
    {
    this.m_events_serializable = p_ser;
    }
  }

File Information:

file name:SearchEngine.java
package:org.dgpf.search.api
qualified name:org.dgpf.search.api.SearchEngine.java
file type:Java Source File
download location:download http://dgpf.sourceforge.net/source/org/dgpf/search/api/SearchEngine.java
size:21.245 KB (21755 B)
uploaded: 2015-07-22 04:11:00 GMT+0000
last update: 2006-08-24 01:00:08 GMT+0000
last access: 2017-11-19 02:55:19 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 02:55:19 GMT+0000.
Valid CSS Valid XHTML 1.1
Valid RSS SourceForge.net Logo