view trunk/ga_code.d @ 2:9655c8362b25

Added the Perceptron class and the perceptron_test testing program.
author revcompgeek
date Sat, 05 Apr 2008 23:41:30 -0600
parents 4b2e8e8a633e
children
line wrap: on
line source

/++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 + Genetic Algorithm Code Test                            +
 + Author: Matt P.                                        +
 + Version: 0.5                                           +
 +                                                        +
 + Runs a genetic algorithm test using a simple code      +
 + guessing algorithm.                                    +
 +                                                        +
 + Usage: ga_code [options]                               +
 + Options:                                               +
 + -h                                                     +
 +      Prints this information.                          +
 + -v                                                     +
 +      Turns on verbose output.                          +
 + -m float                                               +
 +      Specifies the mutation rate for each generation.  +
 +      Default: 0.05                                     +
 +                                                        +
 + -d float                                               +
 +      Specifies the survival rate for each generation.  +
 +      Default: 0.5                                      +
 +                                                        +
 + -p integer                                             +
 +      Specifies the population for each generation.     +
 +      Default: 1000                                     +
 +                                                        +
 + -l integer                                             +
 +      Specifies how long the code to be guessed is.     +
 +      Default: 20                                       +
 +                                                        +
 + -n integer                                             +
 +      Specifies how many possibilities there are for    +
 +      each character of the code string.                +
 +      Default: 20                                       +
 +                                                        +
 + -r integer                                             +
 +      Specifies the number of times to repeat the test. +
 +      Default: 20                                       +
 +                                                        +
 + -c char                                                +
 +      Specifies the crossover type                      +
 +       s / 1 - One point crossover                      +
 +       t / 2 - Two point crossover                      +
 +       u / 3 - Uniform crossover                        +
 +      Default: s                                        +
 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++/


module ga_code;

import aid.ga;
import tango.math.Random;
import tango.math.Math;
import tango.io.Stdout;
//import tango.text.String;
import Float = tango.text.convert.Float;
import Integer = tango.text.convert.Integer;

import bcd.sys.times;

char[] target;

int numChars = 20;
int stringLen = 20;

double average(double[] array){
	double avg = 0;
	foreach (double v; array)
		avg += v;
	avg /= array.length;
	return avg;
}

double stdDev(double[] array){
	double avg = average(array);
	double stddev = 0;
	foreach (double v; array){
		stddev += (v - avg) * (v - avg);
	}
	stddev = sqrt(stddev/array.length);
	return stddev;
}

class Foo {
	public double calculateFitness(char[] gene){
		double fitness=0;
		for (uint i = 0; i < stringLen; i++){
			if (gene[i] == target[i])
				fitness += 1;
		}
		return fitness;
	}
	
	public char[] getRandomGenotype(){
		char[] t;
		t.length = stringLen;
		for (int i = 0; i < stringLen; i++){
			t[i] = Random.shared.next(numChars) + 'a';
		}
		return t;
	}
	
	public char getRandomChar(uint index){
		return cast(char)(Random.shared.next(numChars)+'a');
	}
}

void usage(){
	auto s = 
		"Usage: ga_test [options]                              \n"
		"Options:                                              \n"
		"-h                                                    \n"
		"     Prints this information.                         \n"
		"-v                                                    \n"
		"     Turns on verbose output.                         \n"
		"-m float                                              \n"
		"     Specifies the mutation rate for each generation. \n"
		"     Default: 0.05                                    \n"
		"                                                      \n"
		"-d float                                              \n"
		"     Specifies the survival rate for each generation. \n"
		"     Default: 0.5                                     \n"
		"                                                      \n"
		"-p integer                                            \n"
		"     Specifies the population for each generation.    \n"
		"     Default: 1000                                    \n"
		"                                                      \n"
		"-l integer                                            \n"
		"     Specifies how long the code to be guessed is.    \n"
		"     Default: 20                                      \n"
		"                                                      \n"
		"-n integer                                            \n"
		"     Specifies how many possibilities there are for   \n"
		"     each character of the code string.               \n"
		"     Default: 20                                      \n"
		"                                                      \n"
		"-r integer                                            \n"
		"     Specifies the number of times to repeat the test.\n"
		"     Default: 20                                      \n"
		"                                                      \n"
		"-c char                                               \n"
		"     Specifies the crossover type                     \n"
		"      s / 1 - One point crossover                     \n"
		"      t / 2 - Two point crossover                     \n"
		"      u / 3 - Uniform crossover                       \n"
		"     Default: s                                         ";
	Stdout(s).newline;
}

void main(char[][] args){
	Foo f = new Foo();
	GeneticAlgorithm ga = new GeneticAlgorithm();
	ga.calculateFitness = &f.calculateFitness;
	ga.getRandomGenotype = &f.getRandomGenotype;
	ga.getRandomChar = &f.getRandomChar;
	ga.fitnessThreshold = stringLen;
	int rep = 20;
	bool dotime=true;
	
	
	for (auto i = 1; i < args.length; i++){
		char[] arg = args[i];
		switch (arg){
			case "-h":
				usage();
				return;
			case "-m":
				ga.mutationRate = Float.parse(args[++i]);
				break;
			case "-d":
				ga.survivalRate = Float.parse(args[++i]);
				break;
			case "-p":
				ga.startPopulation = Integer.parse(args[++i]);
				break;
			case "-l":
				stringLen = Integer.parse(args[++i]);
				ga.fitnessThreshold = stringLen;
				break;
			case "-n":
				numChars = Integer.parse(args[++i]);
				break;
			case "-r":
				rep = Integer.parse(args[++i]);
				break;
			case "-v":
				ga.verbose = true;
				break;
			case "-c":
				auto t  = args[++i];
				switch (t){
					case "s","1":
						ga.crossoverType = 1;
						break;
					case "t","2":
						ga.crossoverType = 2;
						break;
					default:
						ga.crossoverType = 3;
				}
				break;
			case "-b":
				ga.bailout = Integer.parse(args[++i]);
				break;
			case "-t":
				dotime = false;
				break;
			default:
				Stdout.format("Unknown parameter: {}",arg).newline;
				usage();
				return;
		}
	}
	
	target = ga.getRandomGenotype();
	
	double[] time;
	double[] gens;
	long start,end;
	
	for(auto i = 0; i < rep; i++){
		if(dotime) start = iutime();
		uint generations = ga.run();
		if(dotime) end = iutime() - start;
		
		if(dotime) time ~= end;
		gens ~= generations;
	}
	
	if(dotime) Stdout.format("{0}, {1:.5}, {2}, {3:.5}", average(gens),stdDev(gens),average(time),stdDev(time)).newline;
	else Stdout.format("{0}, {1:.5}", average(gens),stdDev(gens)).newline; //", {2}, {3:.5}" ,average(time),stdDev(time)
}