Genetischer Algorithmus
Transcription
Genetischer Algorithmus
Roger Imbach [email protected] Genetischer Algorithmus Roger Imbach [email protected] KBS: Genetischer Algorithmus 1/12 Roger Imbach [email protected] Inhalsverzeichnis Einleitung...................................................................................................................................................3 Was ist ein genetischer Algorithmus ?...................................................................................................3 Was machen genetische Algorithmen ?.................................................................................................3 Vorgehen.....................................................................................................................................................4 Crossover rate...................................................................................................................................4 Mutation ...........................................................................................................................................4 Vorteile .............................................................................................................................................5 Nachteile...........................................................................................................................................5 Anwendungsgebiete...................................................................................................................................5 Beispiel.......................................................................................................................................................6 Resultate..............................................................................................................................................12 KBS: Genetischer Algorithmus 2/12 Roger Imbach [email protected] Einleitung Was ist ein genetischer Algorithmus ? Genetische Algorithmen sind genau genommen heuristische Optimierungsverfahren, d.h. diese Algorithmen produzieren verschiedene Lösungsvorschläge (in mehreren Wiederholungszyklen) welche analysiert werden und anschliessend verschieden kombiniert, verändert und ausgelesen werden (durch bestimmte Heuristiken). Die genetischen Algorithmen gehören zu den evolutionären Algorithmen, wodurch ersichtlich ist dass sich diese, durch wiederholte Anpassung und Änderung, weiter entwickeln und sich verändern. Aufgrund dieser beschriebenen Eigenschaften eignen sich genetische Algorithmen für analytisch nicht lösbare Probleme oder auch für Probleme deren geschlossene Lösung nicht effizient berechnet werden kann (P=NP?). Was machen genetische Algorithmen ? Genetische Algorithmen sind an die Biologie angelehnt und versuchen eigentlich nichts anderes zu machen als Mutter Natur selber. Aus einer Population von Individuen / Lösungen wird ein Paar (zufällig) ausgesucht was gut zu der Lösung des Problems passt. Diese beiden Individuen / Lösungen werden „gepaart“ und solange verschieden kombiniert bis wiederum eine Population von Individuen / Lösungen entsteht und das Ganze von vorne beginnt, dabei wird sogar, wie auch in der Natur, Mutationen Sorge getragen. KBS: Genetischer Algorithmus 3/12 Roger Imbach [email protected] Vorgehen – – – – – – – Initialisierung: Erzeugen einer ausreichend grossen Menge / Population unterschiedlicher „Individuen“ (Lösungskandidaten). Dies ist die erste Generation. Evaluation: Für jeden Lösungskandidaten der aktuellen Generation wird anhand einer Funktion (auch Fitness-Funktion genannt) ein Wert bestimmt, der seine Güte angibt. Selektion: Zufällige Auswahl von Lösungskandidaten aus der aktuellen Generation. Dabei werden Lösungskandidaten mit besseren Zielfunktionswerten mit einer höheren Wahrscheinlichkeit ausgewählt. Rekombination: Die Daten der ausgewählten Individuen werden gemischt und daraus neue Individuen erzeugt. Mutation: Zufällige Veränderung der neuen Individuen (mit einer sehr kleinen Wahrscheinlichkeit werden Bitwerte einfach geswitcht). Auswahl der neuen Individuen für die nachfolgende Generation. Diese Individuen können je nach Implementation aus den neu gebildeten Individuen oder auch zusätzlich aus einem Bestandteil der alten Generation bestehen. Ist ein Abbruchkriterium erreicht wird das Individuum welches am besten der erwarteten Lösung entspricht ausgewählt und das Verfahren beendet, ansonsten wiederholen sich die jeweiligen Schritte. Crossover rate Mit der Crossover rate werden Rekombinationen erstellt. Diese rate gibt an mit welcher Wahrscheinlichkeit 2 Individuen ihre Bits swapen. Crossover funktioniert dabei so dass ein beliebiges Bit (Individuen sind von Vorteil binär codiert) ausgesucht wird und ab dieser Position die beiden Individuen ihre restlichen Bits tauschen. Mutation Wie oben schon beschrieben werden zufällig, mit einer sehr kleinen Wahrscheinlichkeit, einzelne Bits einfach von 0 auf 1 geswitcht und vis versa. Dabei ist anzumerken dass die Wahrscheinlichkeit von niederwärtigen Bits höher ist. KBS: Genetischer Algorithmus 4/12 Roger Imbach [email protected] Vorteile Schnellsten Optimierungsverfahren. Binäre Darstellung der Individuen -> Perfekte Anpassung an aktuelle Rechner. Verwendung mehrerer Individuen -> Parallelisierung. Nachteile Optimalitätsproblem (Ist die Lösung optimal?). Es ist schwer geeignete Mutations – und Rekombinationsverfahren zu finden. Anwendungsgebiete Optimierungsverfahren Genetische Programmierung -> Automatische Generierung von Computerprogrammen Robotik -> Bewegungsabläufe -> Wegfindungsalgorithmen Konstruktion von komplexen Bauteilen Brückenbau Lösung (-sansätze) für Probleme im NP-Raum (N=NP?). -> Optimalitätsprinzip bleibt weiterhin bestehen. KBS: Genetischer Algorithmus 5/12 Roger Imbach [email protected] Beispiel Das Beispiel wurde von der Seite ai-junkies entnommen ( http://www.aijunkie.com/files/GA.java ) und beschäftigt sich damit eine Formel zu finden welche einen Eingabewert berechnet, dabei sind die Operationen *, /, +, - möglich inklusive den Zahlen 0-9. Hier ist der Code: import java.util.*; public class GA { public static void main(String[] args) { new GA().doIt(Integer.parseInt("77")); } // Static info static char[] ltable = {'0','1','2','3','4','5','6','7','8','9','+','-','*','/'}; static int chromoLen = 5; static double crossRate = .7; static double mutRate = .001; static Random rand = new Random(); static int poolSize = 40; // Must be even private void doIt(int target) { int gen=0; // Create the pool ArrayList pool = new ArrayList(poolSize); ArrayList newPool = new ArrayList(pool.size()); // Generate unique cromosomes in the pool for (int x=0;x<poolSize;x++) pool.add(new Chomosone(target)); // Loop until solution is found while(true) { // Clear the new pool newPool.clear(); // Add to the generations gen++; // Loop until the pool has been processed for(int x=pool.size()-1;x>=0;x-=2) { // Select two members Chomosone n1 = selectMember(pool); KBS: Genetischer Algorithmus 6/12 Roger Imbach [email protected] Chomosone n2 = selectMember(pool); // Cross over and mutate n1.crossOver(n2); n1.mutate(); n2.mutate(); // Rescore the nodes n1.scoreChromo(target); n2.scoreChromo(target); // Check to see if either is the solution if (n1.total == target && n1.isValid()) { System.out.println("Generations: " + gen + " Solution: " + n1.decodeChromo()); return; } if (n2.total == target && n2.isValid()) { System.out.println("Generations: " + gen + " Solution: " + n2.decodeChromo()); return; } } } // Add to the new pool newPool.add(n1); newPool.add(n2); // Add the newPool back to the old pool pool.addAll(newPool); } //---- Chomosone Class ----private Chomosone selectMember(ArrayList l) { // Get the total fitness double tot=0.0; for (int x=l.size()-1;x>=0;x--) { double score = ((Chomosone)l.get(x)).score; tot+=score; } double slice = tot*rand.nextDouble(); // Loop to find the node double ttot=0.0; for (int x=l.size()-1;x>=0;x--) { Chomosone node = (Chomosone)l.get(x); ttot+=node.score; if (ttot>=slice) { l.remove(x); return node; } } return (Chomosone)l.remove(l.size()-1); } KBS: Genetischer Algorithmus 7/12 Roger Imbach [email protected] // Genetic Algorithm Node private static class Chomosone { // The chromo StringBuffer chromo = new StringBuffer(chromoLen * 4); public StringBuffer decodeChromo = new StringBuffer(chromoLen * 4); public double score; public int total; // Constructor that generates a random public Chomosone(int target) { // Create the full buffer for(int y=0;y<chromoLen;y++) { // What's the current length int pos = chromo.length(); // Generate a random binary integer String binString = Integer.toBinaryString(rand.nextInt(ltable.length)); int fillLen = 4 - binString.length(); // Fill to 4 for (int x=0;x<fillLen;x++) chromo.append('0'); // Append the chromo chromo.append(binString); } // Score the new cromo scoreChromo(target); } public Chomosone(StringBuffer chromo) { this.chromo = chromo; } // Decode the string public final String decodeChromo() { // Create a buffer decodeChromo.setLength(0); // Loop throught the chromo for (int x=0;x<chromo.length();x+=4) { // Get the int idx = Integer.parseInt(chromo.substring(x,x+4), 2); if (idx<ltable.length) decodeChromo.append(ltable[idx]); } } // Return the string return decodeChromo.toString(); // Scores this chromo KBS: Genetischer Algorithmus 8/12 Roger Imbach [email protected] public final void scoreChromo(int target) { total = addUp(); if (total == target) score = 0; score = (double)1 / (target - total); } // Crossover bits public final void crossOver(Chomosone other) { // Should we cross over? if (rand.nextDouble() > crossRate) return; // Generate a random position int pos = rand.nextInt(chromo.length()); // Swap all chars after that position for (int x=pos;x<chromo.length();x++) { // Get our character char tmp = chromo.charAt(x); // Swap the chars chromo.setCharAt(x, other.chromo.charAt(x)); other.chromo.setCharAt(x, tmp); } } // Mutation public final void mutate() { for (int x=0;x<chromo.length();x++) { if (rand.nextDouble()<=mutRate) chromo.setCharAt(x, (chromo.charAt(x)=='0' ? '1' : '0')); } } // Add up the contents of the decoded chromo public final int addUp() { // Decode our chromo String decodedString = decodeChromo(); // Total int tot = 0; // Find the first number int ptr = 0; while (ptr<decodedString.length()) { char ch = decodedString.charAt(ptr); if (Character.isDigit(ch)) { tot=ch-'0'; ptr++; KBS: Genetischer Algorithmus 9/12 Roger Imbach [email protected] } break; } else { ptr++; } // If no numbers found, return if (ptr==decodedString.length()) return 0; // Loop processing the rest boolean num = false; char oper=' '; while (ptr<decodedString.length()) { // Get the character char ch = decodedString.charAt(ptr); // Is it what we expect, if not - skip if (num && !Character.isDigit(ch)) {ptr++;continue;} if (!num && Character.isDigit(ch)) {ptr++;continue;} // Is it a number if (num) { switch (oper) { case '+' : case '-' : case '*' : case '/' : break; } { { { { tot+=(ch-'0'); break; } tot-=(ch-'0'); break; } tot*=(ch-'0'); break; } if (ch!='0') tot/=(ch-'0'); } } else { oper = ch; } } // Go to next character ptr++; num=!num; return tot; } public final boolean isValid() { // Decode our chromo String decodedString = decodeChromo(); boolean num = true; for (int x=0;x<decodedString.length();x++) { char ch = decodedString.charAt(x); // Did we follow the num-oper-num-oper-num patter if (num == !Character.isDigit(ch)) return false; KBS: Genetischer Algorithmus 10/12 Roger Imbach [email protected] // Don't allow divide by zero if (x>0 && ch=='0' && decodedString.charAt(x-1)=='/') return false; num = !num; } // Can't end in an operator if (! Character.isDigit(decodedString.charAt(decodedString.length()-1))) return false; } } return true; } Wir sehen dass ich den Eingabewert 77 gewählt habe und die Länge der Chromosomen auf 5 gesetzt wurde (sprich die Lösung hat 5 Bestandteile (Operationen + Zahlen)), wie auch die Mutationsrate und Crossoverrate. Wir sehen dass der Algorithmus nichts anderes macht als wir bereits besprochen haben. 1. Generation erstellen 2. Chromosomen aussuchen 3. Chromosomen „paaren“ (Crossover) 4. Chromosomen mutieren 5. Chromosomen neu bewerten(Fitting) 6. Schauen ob wir einen korrekten Wert gefunden haben 7. Ansonsten wiederholen bis Lösung gefunden wurde Wie die ganzen Operationen auf den Chromosomen durchgeführt werden ist wirklich gut im Code ersichtlich, die Prinzipien erfolgen auch den in der Einleitung beschriebenen Ideen. KBS: Genetischer Algorithmus 11/12 Roger Imbach [email protected] Resultate Ich habe die Zahl 77 gewählt. Hier einige Lösungen: Generations: Generations: Generations: Generations: Generations: Generations: 543 Solution: 9*8+5 3872 Solution: 9*8+5 6710 Solution: 7+4*7 2270 Solution: 9*9-4 2274 Solution: 9*9-4 2090 Solution: 7+4*7 Auffällig daran ist dass die Anzahl der Generationen ziemlich hoch ist, das Ganze jedoch ziemlich schnell abläuft. Die Resultate ähneln sich auch ziemlich, was aufgrund der Beschränkung der Chromosomenlänge auf 5 und der Wahl der Zahl einleuchtend ist, denn 77 besitzt in der Primzahlenzerlegung die Primzahlen 7 und 11, welche in einigen der Lösungen vorkommen (7+4 = 11 * 7 = 77) und diese sich auf wenige verschiedene Arten bilden lassen (zumindest im Vergleich mit nicht Primzahlen). Wie es zu der Berechnung der Zahl kommt ist in den Beschreibungen ganz gut ersichtlich. Quellen http://www.ai-junkie.com/ga/intro/gat1.html http://de.wikipedia.org/wiki/Genetischer_Algorithmus http://www.ai-junkie.com/files/GA.java KBS: Genetischer Algorithmus 12/12