Package fmg.fmg8.endlAutomat.rekombination

Source Code of fmg.fmg8.endlAutomat.rekombination.RekTrivial

/*
* Datei: RekombinationTrivial.java
* Autor(en):        Lukas K�nig
* Java-Version:     1.4
* Erstellt (vor):   17.12.2007
*
* (c) Lukas K�nig, die Datei unterliegt der LGPL
* -> http://www.gnu.de/lgpl-ger.html
*/

package fmg.fmg8.endlAutomat.rekombination;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Random;

import fmg.fmg8.endlAutomat.RobCode;
import fmg.fmg8.endlAutomat.conditions.Condition;
import fmg.fmg8.sonstiges.SonstMeth;
import fmg.fmg8.umgebung2D.Roboter;

/**
* Implementiert eine triviale Rekombination, bei der in Abh�ngigkeit von der
* Fitness mit gr��erer Wahrscheinlichkeit das bessere Genom (von zweien)
* zur�ckgegeben wird.
*
* @author Lukas K�nig
*/
public class RekTrivial implements RekVerfahren {

    /**
     * Die Anzahl der Eltern.
     */
    private int anzElt;
   
    /**
     * Die Anzahl der Kinder.
     */
    private int anzKind;
   
    /**
     * Ob die Anzahl der Kinder maximal die Gr��e der urspr�nglichen
     * Population sein soll.
     */
    private boolean normieren;
   
    /**
     * Die gr��te m�gliche zur�ckgegebene Populationsgr��e.
     */
    private int maxPopSize;
   
    /**
     * Der Zufallsgenerator.
     */
    private Random rand;
   
    /**
     * Erzeugt ein Objekt der Klasse RekombinationTrivial, wobei eine
     * Rekombination mit der angegebenen Anzahl von Eltern und Kinder
     * eingestellt wird. Die Auswirkung auf die Anzahl der Individuen in der
     * Kindpopulation muss jedoch erst daraus abgeleitet werden. Bitte die
     * �brigen Kommentare beachten!
     *
     * @param anzEltern  Die Anzahl der Eltern, die bei einer Rekombination
     *                   betrachtet werden sollen.
     * @param anzKinder  Die Anzal der Kinder, die erzeugt werden sollen.
     * @param norm       Ob die Anzahl der Kinder maximal die Anzahl der
     *                   Eltern sein soll.
     * @param maxChild   Die gr��te m�gliche zur�ckgegebene Populationsgr��e.
     * @param random     Der Zufallsgenerator.
     */
    public RekTrivial(
            final int     anzEltern,
            final int     anzKinder,
            final boolean norm,
            final int     maxChild,
            final Random  random) {
        this.anzElt = anzEltern;
        this.anzKind = anzKinder;
        this.normieren = norm;
        this.rand = random;
        this.maxPopSize = maxChild;
    }
   
    /**
     * Erzeugt soviele Kinder wie angegeben, wobei der beste Automat der Liste
     * (im Sinne der Fitnessfunktion) geklont wird. Wenn es mehre gleich gute
     * beste gibt, wird der erste beste Automat genommen. Die Fitness wird
     * auch bei allen Kindern auf den Wert des Automaten des besten Elternteils
     * gesetzt. Dieses Vorgehen wird, falls ein Roboter mehrere Automaten hat,
     * f�r jeden Automaten einzeln durchgef�hrt.
     * <BR>
     * Bei so vielen Kinder wie es Eltern gibt wird als ID die ID eines
     * Elternteils benutzt, um eine sp�tere Zuordnung zu einem Elternteil
     * zu erm�glichen. Bei allen �brigen Kindern (falls vorhanden) wird die
     * ID auf den ung�ltigen Wert -1 gesetzt. Insbesondere kann f�r Kinder > 1
     * vorkommen, dass mehrere Kinder dieselbe ID haben: die zur�ckgegebenen
     * Kinder stellen also im Allgemeinen KEINE g�ltige Population dar.
     *
     * @param rob  Die Roboter.
     *
     * @return  Die neue Roboterliste als Tupel (ID, Fitness, Code).
     */
    @SuppressWarnings(value = { "unchecked" })
    public RobCode[] rekombEinz(final Roboter[] rob) {
        int[] bestFit = new int[rob[0].vAuts().length];
        int[] bestInd = new int[rob[0].vAuts().length];
        RobCode[] kinder = new RobCode[this.anzKind];
        Condition[] conds;
        int id;
        int[] fits = new int[rob[0].vAuts().length];
       
        String[] transStdCodes = new String[rob[0].vAuts().length];
        LinkedList<Integer>[] verhCodes
            = new LinkedList[rob[0].vAuts().length];
        LinkedList<Integer>[] transCodes
            = new LinkedList[rob[0].vAuts().length];
       
        // Bestes Individuum suchen.
        for (int j = 0; j < rob[0].vAuts().length; j++) {
            bestFit[j] = Integer.MIN_VALUE;
            bestInd[j] = 0;
        }
       
        for (int i = 0; i < rob[0].vAuts().length; i++) {
            for (int j = 0; j < rob.length; j++) {
                if (rob[j] != null && bestFit[i] < rob[j].getFitness()[i]) {
                    bestFit[i] = rob[j].getFitness()[i];
                    bestInd[i] = j;
                }
            }
        }

        // Bestes Individuum merken.
        for (int i = 0; i < rob[0].vAuts().length; i++) {
            verhCodes[i] = rob[bestInd[i]].getVerhCodes()[i];
            transCodes[i] = rob[bestInd[i]].getTransCodes()[i];
            transStdCodes[i] = rob[bestInd[i]].getTransStdCodes()[i];
            fits[i] = rob[bestInd[i]].getFitness()[i];
        }
       
        // Neue Robcodes als Klone des besten erzeugen.
        for (int i = 0; i < this.anzKind; i++) {

            if (i < rob.length) {
                id = rob[i].getId();
                conds = rob[i].getConds(); // TODO
            } else {
                id = rob[0].getId();
                conds = rob[0].getConds(); // TODO
            }
           
            kinder[i] = new RobCode(
                    id,
                    fits,
                    SonstMeth.stringAusListSeqs(verhCodes),
                    conds,
                    transStdCodes,
                    SonstMeth.stringAusListSeqs(transCodes),
                    SonstMeth.stringAusListSeqs(verhCodes));
        }
       
        return kinder;
    }
   
    /**
     * F�hrt eine Rekombination der gesamten Population durch. Die
     * Rekombination geschieht auf Basis der Methode <code>rekombEinz</code>.
     * Es werden die am n�chsten zusammenstehenden Roboter rekombiniert.
     * <BR>
     * Zu beachten ist, dass von JEDEM Roboter aus einmal die n�chsten
     * berechnet und diese zusammen zu Kindern rekombiniert werden.
     * Um die Population bei gleicher Gr��e zu belassen, gen�gt also ein
     * Verh�ltnis (Eltern / Kinder) = N / 1. Bei dieser Rekombination ist
     * es nicht m�glich, eine Kindpopulation zu erzeugen, die kleiner ist als
     * die Elternpopulation (au�er durch setzen des Normierungsattributs).
     *
     * @param elternPop  Die zu rekombinierende Population von Robotern.
     *
     * @return  Die rekombinierte Population als Tupel (ID, Code).
     */
    public ArrayList<RobCode> rekombiniere(
            final ArrayList<Roboter> elternPop) {
        Iterator<Roboter> it;
        Roboter rob1;
        Roboter rob2;
        Roboter[] eltern = new Roboter[this.anzElt];
        RobCode[] kinder;
        ArrayList<RobCode> kindPop = new ArrayList<RobCode>();
        HashSet<Roboter> nicht = new HashSet<Roboter>(this.anzElt);
       
        it = elternPop.iterator();
        while (it.hasNext()) {
            nicht.clear();
            rob1 = it.next();
            eltern[0] = rob1;
            nicht.add(rob1);
           
            for (int i = 1; i < this.anzElt; i++) {
                rob2 = rob1.getUmg().holeNahenNorm(
                        (int) rob1.getPosition().x,
                        (int) rob1.getPosition().y,
                        nicht);
                if (rob2 == null) {
                    rob2 = rob1;
                }
               
                nicht.add(rob2);
                eltern[i] = rob2;
            }
           
             kinder = this.rekombEinz(eltern);
           
            for (int i = 0; i < this.anzKind; i++) {
                kindPop.add(kinder[i]);
            }
        }

        if (this.normieren) {
            while (kindPop.size() > elternPop.size()) {
                kindPop.remove(this.rand.nextInt(kindPop.size()));
            }
        }
       
        while (kindPop.size() > this.maxPopSize) {
            kindPop.remove(this.rand.nextInt(kindPop.size()));
        }
       
        return kindPop;
    }
}
TOP

Related Classes of fmg.fmg8.endlAutomat.rekombination.RekTrivial

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.