package org.dgpf.search.api.halt;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import org.dgpf.search.api.Individual;
import org.dgpf.search.api.HaltParameters;
import org.dgpf.search.api.SearchState;
import org.dgpf.search.api.SearchUtils;
/**
* The search halt parameters can be used to specify when a search should
* stop all its work.
*
* @author Thomas Weise
*/
public class DefaultHaltParameters extends HaltParameters
{
/**
* The serial version uid.
*/
private static final long serialVersionUID = 1;
/**
* The maximum count of updates to process. The Engine will halt when
* this count is exceeded.
*/
long m_max_updates ;
/**
* The maximum relative time how long the search engineering may take in
* milliseconds. If you specify this parameter, searching may
* only halt after finishing one update. This leads to fuzzy
* interpretation of the maximum time, the system may use more time than
* specified.
*/
long m_max_time ;
/**
* This array contains the fitness thresholds. If the supremum meets all
* thresholds provided, the search can be terminated globally.
*/
transient double[] m_thresholds ;
/**
* Create a new instance of <code>DefaultHaltParameters</code>.
* @param p_fitness_function_count The count of fitness functions.
*/
public DefaultHaltParameters (final int p_fitness_function_count)
{
super();
this.m_max_updates = Long.MAX_VALUE;
this.m_max_time = Long.MAX_VALUE;
this.m_thresholds = new double[p_fitness_function_count];
}
/**
* The maximum count of updates to process. The Engine will halt when
* this count is exceeded. Pass in a value <= 0 if you dont want to
* specify a maximum update count.
* This parameter may be <= 0 if no update limit has been set.
* @return The maximum count of updates.
*/
public final long get_max_updates ()
{
return this.m_max_updates;
}
/**
* Set the maximum count of updates to process. The Engine will halt
* when this count is exceeded. Pass in a value <= 0 if you dont want to
* specify a maximum updates count.
* This parameter may be <= 0 if no update limit has been set.
* @param p_max_updates The maximum count of updates.
*/
public final void set_max_updates (final long p_max_updates)
{
this.m_max_updates = ((p_max_updates <= 0) ? Long.MAX_VALUE
: p_max_updates);
}
/**
* If you specify this parameter, searching may only halt after
* finishing one update. This leads to fuzzy interpretation of the
* maximum time, the system may use more time than specified.
* This parameter may be <= 0 if no time limit has been set.
* @return The maximum allowed time for searching.
*/
public final long get_max_time ()
{
return this.m_max_time;
}
/**
* If you specify this parameter, searching may only halt after
* finishing one update. This leads to fuzzy interpretation of the
* maximum time, the system may use more time than specified.
* This parameter may be <= 0 if no time limit has been set.
* @param p_max_time The maximum allowed time for searching.
*/
public final void set_max_time (long p_max_time)
{
this.m_max_time = ((p_max_time <= 0) ? Long.MAX_VALUE
: p_max_time);
}
/**
* Obtain the fitness threshold defined for the specified fitness function.
* If the supremum meets all thresholds provided, the search can be
* terminated globally.
* @param p_function The fitness function of concern.
* @return The fitness threshold defined for the specified fitness function.
*/
public final double get_fitness_threshold (final int p_function)
{
return this.m_thresholds[p_function];
}
/**
* Set the fitness threshold for a specified fitness function.
* @param p_threshold The new fitness function threshold, or <code>0</code>
* if you don't want to specify a threshold value for
* this particular fitness function.
* @param p_function The fitness function of concern.
*/
public final void set_fitness_threshold (final int p_function,
final double p_threshold)
{
this.m_thresholds[p_function] = SearchUtils.format_positive(p_threshold);
}
/**
* Check wether at least one of the halt criterions is met. This method
* tells the search engine wether it should continue processing
* (<code>GO_ON</code>), wether it should abort locally (<code>ABORT</code>)
* or if all search engines in the network should stop working.
* (<code>SHUTDOWN</code>)
* @param p_state The state of the search engine.
* @return <code>GO_ON</code> if the searching should continue,
* <code>ABORT</code> if the local search engine should abort,
* <code>SHUTDOWN</code> if all searching activities should end
* throughout the network
* @see #GO_ON
* @see #ABORT
* @see #SHUTDOWN
*/
@Override
protected HaltType should_halt (final SearchState<?> p_state)
{
boolean l_b;
final Individual<?> l_id;
int l_i;
double l_d;
final double[] l_dd;
if((p_state.get_update_count() >= this.m_max_updates) ||
(p_state.get_total_time() >= this.m_max_time))
{
return ABORT;
}
l_dd = this.m_thresholds;
l_b = false;
l_id = p_state.get_best();
for(l_i = (l_dd.length-1); l_i >= 0; l_i--)
{
l_d = l_dd[l_i];
if(l_d > 0.0d)
{
if(l_d > l_id.get_fitness(l_i)) return GO_ON;
l_b = true;
}
}
return (l_b ? SHUTDOWN : GO_ON);
}
/**
* Obtain the count of fitness functions evaluated by this search.
* @return The count of fitness functions evaluated by this search.
*/
public final int get_fitness_function_count()
{
return this.m_thresholds.length;
}
/**
* Create of copy of this halt parameters instance.
* @return A copy of this halt parameters instance.
*/
@Override
public Object clone ()
{
DefaultHaltParameters l_dh;
l_dh = ((DefaultHaltParameters)(super.clone()));
l_dh.m_thresholds = l_dh.m_thresholds.clone();
return l_dh;
}
/**
* Stores the <code>SfcEvent</code> into the stream.
* @param p_s The output stream.
* @throws IOException If something io-like went wrong.
*/
private final void writeObject(final ObjectOutputStream p_s)
throws IOException
{
p_s.defaultWriteObject();
p_s.writeUnshared(this.m_thresholds);
}
/**
* Reconstitute the <code>SfcEvent</code> instance from a stream (that is,
* deserialize it).
* @param p_s The input stream.
* @throws IOException If something io-like went wrong.
* @throws ClassNotFoundException If a needed class could not be found.
*/
private final void readObject(final ObjectInputStream p_s)
throws IOException, ClassNotFoundException
{
p_s.defaultReadObject();
this.m_thresholds = ((double[])(p_s.readUnshared()));
}
}