package gp;
import java.util.Arrays;
import java.util.Random;
import java.util.Vector;
class RatedIndividual implements Comparable<RatedIndividual>
{
public InterfaceIndividual indy;
public double val;
public RatedIndividual(InterfaceIndividual individual, double value)
{
indy = individual;
val = value;
}
public int compareTo(RatedIndividual y)
{
double w = y.val;
if (val<w) return -1;
else {
if (val>w) return 1;
else return 0;
}
}
}
enum SelectionEnum {
best, nonlinRank;
}
/**
* Selection class.
*/
public class Selection {
// Selection enthaelt Selektionsmethoden fuer den Algorithmus EvolutionaryAlgorithm.java.
// Die Auswahl wird ueber das GUI getroffen und als Parameter an den Konstruktor uebergeben.
static double worstFit=Math.pow(10,100);
double selParam;
double sigmaShare;
EaGuiCallback gcb;
int tAct;
SelectionEnum method;
boolean doSharing;
public Selection(SelectionEnum meth, double selP, Random random, EaGuiCallback g, boolean doShare, double sigShare)
{
// Initialisiert ein Selection-Objekt mit Hilfe der von der GUI übergebenen Parameter.
init(meth, selP, random, g, doShare, sigShare);
}
public Selection(SelectionEnum meth, double selP, Random random, EaGuiCallback g)
{
// Initialisiert ein Selection-Objekt mit Hilfe der von der GUI übergebenen Parameter.
init(meth, selP, random, g, false, 1);
}
protected void init(SelectionEnum meth, double selP, Random random, EaGuiCallback g, boolean doShare, double sigShare) {
selParam = selP;
gcb = g;
tAct = 0;
method = meth;
doSharing = false;
sigmaShare = 10.;
}
public Vector<InterfaceIndividual> generateMatingPool(InterfaceIndividual[] pop)
{
// Gibt einen Vektor aus Individual zurueck, abhaengig von der gewaehlten Methode.
switch (method)
{
case best: return best(pop);
case nonlinRank: return nonlinRanking(pop);
}
System.err.println("Selection method not implemented!");
return null;
}
public InterfaceIndividual findBest(InterfaceIndividual[] pop)
{
// Gibt das beste Individuum aus pop zurueck.
RatedIndividual a[] = scanPopulation(pop);
return a[0].indy;
}
public void printBest(InterfaceIndividual[] pop, int n)
{
// Gibt das beste Individuum aus pop zurueck.
RatedIndividual a[] = scanPopulation(pop);
for (int i=0; i<n; i++) System.out.println(a[i].indy);
}
Vector<InterfaceIndividual> stochasticUniversalSampling(RatedIndividual[] a) {
// Gibt einen Vektor aus Individual zurueck, erzeugt nach der Methode Stochastic Universal Sampling.
// Grundlegend ist, dass die Summe der Bewertungen a[i].v gleich der Populationsgroesse n ist.
// Dann werden n Individuen ausgewaehlt. z wird zufaellig initialisiert und spiegelt die Position
// des ersten Zeigers wieder. Alle anderen Zeiger folgen im Abstand 1. Fuer jeden Abschnitt a[i].v
// des Gluecksrads wird geprueft, wie viele Zeiger darauf zeigen.
double s=0, z=RandomNumberGenerator.randomDouble();
int i, n=a.length;
Vector<InterfaceIndividual> matingPool = new Vector<InterfaceIndividual>();
for (i=0; i<n; i++) {
s += a[i].val;
while (s>z) {matingPool.add(a[i].indy); z++;}
}
return matingPool;
}
RatedIndividual[] scanPopulation(InterfaceIndividual[] pop)
{
// Erzeugt ein sortiertes RatedIndividual-Array aus einem Individual-Array,
// indem fuer jedes Individual seine Funktion eval() ausgewertet wird.
// Ausserdem werden bester, mittlerer und schlechtester Fitnesswert in der GUI dargestellt.
int i, n=pop.length;
double fit, sum=0;
double worst=Double.NEGATIVE_INFINITY;
RatedIndividual a[] = new RatedIndividual[n];
for (i=0; i<n; i++)
{
fit=pop[i].evaluate();
if (Double.isInfinite(fit)) fit = worstFit;
sum+=fit;
a[i] = new RatedIndividual(pop[i], fit);
if (fit > worst) worst = fit;
}
Arrays.sort(a);
if (gcb!=null) {
if (tAct == 0) System.out.println("t Best Mean Worst");
gcb.plotFit(tAct++,a[0].val,sum/n,a[n-1].val, a[0].indy);
}
else System.out.println(tAct + " " + a[0].val + " " + sum/n + " " + a[n-1].val);
return a;
}
Vector<InterfaceIndividual> dummy(InterfaceIndividual[] pop)
{
int i, n=pop.length;
RatedIndividual a[] = scanPopulation(pop);
Vector<InterfaceIndividual> matingPool = new Vector<InterfaceIndividual>();
for (i=0; i<n; i++) matingPool.add(a[i].indy);
return matingPool;
}
Vector<InterfaceIndividual> best(InterfaceIndividual[] pop)
{
int i, n=pop.length;
RatedIndividual a[] = scanPopulation(pop);
Vector<InterfaceIndividual> matingPool = new Vector<InterfaceIndividual>();
for (i=0; i<n; i++) matingPool.add(a[0].indy);
return matingPool;
}
Vector<InterfaceIndividual> linRanking(InterfaceIndividual[] pop) {
// Gibt einen Vektor aus Individual zurueck gemaess linearem Ranking.
// Der Parameter selemParam aus der GUI entspricht eta^+ im Abschnitt 5.6.3 des Skripts.
// (eta^+)-(eta^-) ist somit 2*(selParam-1).
// Die -1 im Skript fuer den Index i entfaellt aufgrund des Startwerts 0.
// Der Faktor 1/lambda im Skript entfaellt aufgrund der Reskalierung, bei der
// die Bewertungen mit der Populationsgroesse multipliziert werden.
int i, n=pop.length;
RatedIndividual a[] = scanPopulation(pop);
double Ediff = 2*(selParam-1)/(n-1);
for (i=0; i<n; i++) a[i].val = selParam-Ediff*i;
return stochasticUniversalSampling(a);
}
Vector<InterfaceIndividual> nonlinRanking2(InterfaceIndividual[] pop) {
// Gibt einen Vektor aus Individual zurueck gemaess nichtlinearem Ranking, Variante, die
// keine Reskalierung benötigt.
// Die Bewertungen der Individuen wird dazu fuer stochasticUniversalSampling() skaliert.
int i, n=pop.length;
RatedIndividual a[] = scanPopulation(pop);
double s = n/Math.pow(n,selParam);
for (i=0; i<n; i++) {
a[i].val = (Math.pow(n-i,selParam)-Math.pow(n-i-1,selParam))*s;
}
return stochasticUniversalSampling(a);
}
Vector<InterfaceIndividual> nonlinRanking(InterfaceIndividual[] pop) {
int i, n=pop.length;
RatedIndividual a[] = scanPopulation(pop);
double sum = 0.;
// Compute expected number of descendants for each individual based on its rank
for (i=0; i<n; i++) {
a[i].val = selParam * Math.pow((1. - selParam), ((double) i)) * n;
sum += a[i].val;
}
// Rescaling is necessary
double factor = (double) n / sum;
sum = 0.;
for (i=0; i<n; i++) {
a[i].val *= factor;
sum += a[i].val;
}
// If the total sum not equals n, then add the difference to the first element!
if(sum < n) {
double diff = (double) n - sum;
a[0].val += diff;
sum += diff;
}
return stochasticUniversalSampling(a);
}
}