package org.dgpf.search.api.comparators;
import org.dgpf.search.api.Individual;
import org.dgpf.search.api.IndividualComparator;
/**
* This comparator transforms the multi-objective genetic algorithm into a
* single-objective one by simple adding up all the fitness functions and
* comparing one total fitness.
*
* @author Thomas Weise
*/
public class SumComparator extends IndividualComparator
{
/**
* The serial version uid.
*/
private static final long serialVersionUID = 1;
/**
* The globally shared instance of this comparator.
*/
public static final IndividualComparator INSTANCE =
new SumComparator();
/**
* The internal constructor stops you from instantiating this class.
* Use <code>INSTANCE</code> to obtain the shared instance.
* @see #INSTANCE
*/
private SumComparator()
{
super();
}
/**
* <p>
* Compares its two individuals for fitness. Returns a negative integer,
* zero, or a positive integer as the first argument is fitter than, equal
* to, or less fit than the second.
* </p>
* @param p_i1 The first individual to be compared.
* @param p_i2 The second individual to be compared.
* @return a negative integer, zero, or a positive integer as the
* first individual is fitter than, equal to, or less fit than the
* second.
* @throws ClassCastException if the arguments' types prevent them from
* being compared by this Comparator.
*/
@Override
public final int compare(final Individual<?> p_i1,
final Individual<?> p_i2)
{
final double l_res;
l_res = this.get_scalar_difference(p_i1, p_i2);
return ((l_res < 0.0d) ? -1 : ((l_res == 0.0d) ? 0 : 1));
}
/**
* <p>
* Obtain the scalar difference of two individuals. This method is
* compatible with <code>compare</code> by fulfilling the contract that
* <code>sign(compare(a,b)) == sign(get_scalar_difference(a,b))</code>
* where <code>sign(x)</code> computes the sign of the number
* <code>x</code>. <code>get_scalar_difference</code> is used by some
* search techniques that require a numeric resolution of the comparison
* of two individuals more precise than <code>compare</code> can deliver.
* However, <code>compare</code> should be the prefered way to compare
* two individuals.
* </p>
* <p>TODO: Check whether a vector norm would be better here than just the
* fitness scalar sum.</p>
* @param p_i1 The first individual to be compared.
* @param p_i2 The second individual to be compared.
* @return a negative double, zero, or a positive double as the
* first individual is fitter than, equal to, or less fit than the
* second denoting the difference of the two individuals.
* @throws ClassCastException if the arguments' types prevent them from
* being compared by this Comparator.
* @see #compare(Individual, Individual)
*/
@Override
public final double get_scalar_difference(final Individual<?> p_i1,
final Individual<?> p_i2)
{
int l_i;
double l_res;
l_res = 0.0d;
for(l_i = (p_i1.get_fitness_function_count()-1); l_i >= 0; l_i--)
{
l_res += (p_i2.get_fitness(l_i) - p_i1.get_fitness(l_i));
}
return l_res;
}
/**
* Deserialize to the proper instance.
* @return The globally shared instance.
*/
private final Object readResolve()
{
return INSTANCE;
}
/**
* Perform a write replace of this object.
* @return The object to store.
*/
private final Object writeReplace()
{
return INSTANCE;
}
/**
* Create of copy of this halt parameters instance.
* @return A copy of this halt parameters instance.
*/
@Override
public final Object clone ()
{
return INSTANCE;
}
/**
* Check whether this comparator equals another object.
* @param p_object The object to compare with.
* @return <code>true</code> if and only if <code>p_object</code> is also
* an individual comparator and will always return the same result
* for all possible comparisons to be performed.
*/
@Override
public final boolean equals (final Object p_object)
{
return ((p_object == this) ||
(p_object instanceof SumComparator));
}
}