Genetic Algorithm OverflowException: Number overflow:
Hi i'm starting on genetic algorithm and i'm getting and overflow error, i know i'm getting a negative array on line 34 of my script and i think it's because it;s not getting initialized, i'm trying to make an AI that runs through and obstacle course and learns it through generations please help I apologize for the amount of code
using System; using System.Collections.Generic;
public class GeneticAlgorithm<T>
{
public List<DNA<T>> Population { get; private set; }
public int Generation { get; private set; }
public float BestFitness { get; private set; }
public T[] BestGenes { get; private set; }
public int Elitism;
public float MutationRate;
private List<DNA<T>> newPopulation;
private Random random;
private float fitnessSum;
private int dnaSize;
private Func<T> getRandomGene;
private Func<int, float> fitnessFunction;
public GeneticAlgorithm(int populationSize, int dnaSize, Random random, Func<T> getRandomGene, Func<int, float> fitnessFunction,
int elitism, float mutationRate = 0.01f)
{
Generation = 1;
Elitism = elitism;
MutationRate = mutationRate;
Population = new List<DNA<T>>(populationSize);
newPopulation = new List<DNA<T>>(populationSize);
this.random = random;
this.dnaSize = dnaSize;
this.getRandomGene = getRandomGene;
this.fitnessFunction = fitnessFunction;
BestGenes = new T[dnaSize]; /*This is the array that gives me trouble*/
for (int i = 0; i < populationSize; i++)
{
Population.Add(new DNA<T>(dnaSize, random, getRandomGene, fitnessFunction, shouldInitGenes: true));
}
}
public void NewGeneration(int numNewDNA = 0, bool crossoverNewDNA = false)
{
int finalCount = Population.Count + numNewDNA;
if (finalCount <= 0) {
return;
}
if (Population.Count > 0) {
CalculateFitness();
Population.Sort(CompareDNA);
}
newPopulation.Clear();
for (int i = 0; i < Population.Count; i++)
{
if (i < Elitism && i < Population.Count)
{
newPopulation.Add(Population[i]);
}
else if (i < Population.Count || crossoverNewDNA)
{
DNA<T> parent1 = ChooseParent();
DNA<T> parent2 = ChooseParent();
DNA<T> child = parent1.Crossover(parent2);
child.Mutate(MutationRate);
newPopulation.Add(child);
}
else
{
newPopulation.Add(new DNA<T>(dnaSize, random, getRandomGene, fitnessFunction, shouldInitGenes: true));
}
}
List<DNA<T>> tmpList = Population;
Population = newPopulation;
newPopulation = tmpList;
Generation++;
}
private int CompareDNA(DNA<T> a, DNA<T> b)
{
if (a.Fitness > b.Fitness) {
return -1;
} else if (a.Fitness < b.Fitness) {
return 1;
} else {
return 0;
}
}
private void CalculateFitness()
{
fitnessSum = 0;
DNA<T> best = Population[0];
for (int i = 0; i < Population.Count; i++)
{
fitnessSum += Population[i].CalculateFitness(i);
if (Population[i].Fitness > best.Fitness)
{
best = Population[i];
}
}
BestFitness = best.Fitness;
best.Genes.CopyTo(BestGenes, 0);
}
private DNA<T> ChooseParent()
{
double randomNumber = random.NextDouble() * fitnessSum;
for (int i = 0; i < Population.Count; i++)
{
if (randomNumber < Population[i].Fitness)
{
return Population[i];
}
randomNumber -= Population[i].Fitness;
}
return null;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GAManager : MonoBehaviour {
private GeneticAlgorithm<MovementData> ga;
private System.Random random;
//Movement
Transform finish;
Transform start;
float xstart;
float xfinish;
int distance;
int topScore = 15;
int maxSpeed = 15;
int minSpeed = 1;
int maxJump = 15;
int minJump = 1;
//Genetic Algorithm
public int populationSize = 1;
int elitism = 1;
float mutationRate = 0.01f;
// Use this for initialization
void Start () {
finish = GameObject.Find("Finish").GetComponent<Transform>();
start = GameObject.Find("Start").GetComponent<Transform>();
xstart = start.position.x;
xfinish = finish.position.y;
distance = (int)xstart - (int)xfinish;
random = new System.Random();
ga = new GeneticAlgorithm<MovementData>(populationSize, distance, random, GetRandomMovement, FitnessFunction, elitism, mutationRate);
}
// Update is called once per frame
void Update () {
}
public MovementData GetRandomMovement ()
{
MovementData movementData = new MovementData();
movementData.speed = Random.Range (minSpeed, maxSpeed);
movementData.jumpForce = Random.Range(minJump, maxJump);
return movementData;
}
private float FitnessFunction(int index)
{
float score = 0;
DNA<MovementData> dna = ga.Population [index];
for (int i = 0; i < dna.Genes.Length; i++)
{
if (dna.Genes [i].distanceAI == distance)
{
score += 1;
}
score += dna.Genes[i].triggersHad / topScore;
}
return score;
}
void OnTriggerEnter(Collider other)
{
MovementData movetriggers = new MovementData ();
if (other.tag == "AddScore") {
Debug.Log("Increase Score");
movetriggers.triggersHad++;
} else if (other.tag == "DecreaseScore") {
Debug.Log("Decrease Score");
movetriggers.triggersHad--;
}
}
}
// This is my the manager that gets all the data i need for the AI
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[Serializable]
public class MovementData
{
public float speed;
public float jumpForce;
public float distanceAI;
public int triggersHad;
}
public class Movement : MonoBehaviour {
public Rigidbody rb;
public float gravity;
public bool hasJumped;
public MovementData movementData;
private GeneticAlgorithm<MovementData> ga;
public enum State
{
Jump,
Run
}
public State state;
// Use this for initialization
void Start () {
rb = GetComponent<Rigidbody>();
state = State.Run;
}
// Update is called once per frame
void Update () {
if (Input.GetButtonDown("Jump"))
{
state = State.Jump;
}
else if(Input.GetButtonUp("Jump"))
{
state = State.Run;
}
switch (state)
{
case State.Jump:
{
Jump();
break;
}
case State.Run:
{
Run();
break;
}
}
}
void Jump()
{
rb.AddForce(Vector3.up * movementData.jumpForce, ForceMode.Impulse);
rb.AddForce(Physics.gravity * gravity, ForceMode.Acceleration);
hasJumped = true;
}
void Run()
{
rb.AddForce(Vector3.right * movementData.speed, ForceMode.Force);
hasJumped = false;
}
}
// And this is a simple AI movement script i made maybe it's relevant thank you for your help
Comment
Your answer
