Genetic Algorithm Function JS 2D arrays

Viewed 48

I am trying to do a basic Genetic algorithm, one of the steps is to generate the next population trough genetic crossing at n points, I have chosen arbitrarily 4. The problem is that my code runs indefinitely unless I stop it. I thought this would only generate 3 offspring. Can anyone tell me why it's being recursive?

let population = [
    [0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
    [0, 1, 1, 1, 0, 0, 1, 1, 0, 1],
    [0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
    [0, 1, 1, 1, 0, 0, 1, 1, 0, 1],
]


kidsFactory()

function kidsFactory() {
    let newKid = []
    let parents = population
    for(i=0; i<(parents.length - 1);i++){
        parent1 = parents[i]
        parent2 = parents[i+1]
        console.log('parent1 '+parent1);
        console.log('parent2 '+parent2);
        newKid.push(parent1[0], parent1[1], parent2[2], parent2[3], parent1[4], parent1[5], parent2[6], parent2[7], parent1[8], parent1[9])
        console.log(newKid);
        population.push(newKid)
        newKid=[]
        console.log(population);
    }
}
2 Answers

The issue is that you are modifying the array while iterating over it, which changes its length. Although it seems you are only modifying population, parents and populations both refer to the same array. You can instead store the length beforehand.

for(let i = 0, len = parents.length; i < len - 1; i++){

let population = [
    [0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
    [0, 1, 1, 1, 0, 0, 1, 1, 0, 1],
    [0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
    [0, 1, 1, 1, 0, 0, 1, 1, 0, 1],
]


kidsFactory()

function kidsFactory() {
    let newKid = []
    let parents = population
    for(let i = 0, len = parents.length; i < len - 1; i++){
        parent1 = parents[i]
        parent2 = parents[i+1]
        console.log('parent1 '+parent1);
        console.log('parent2 '+parent2);
        newKid.push(parent1[0], parent1[1], parent2[2], parent2[3], parent1[4], parent1[5], parent2[6], parent2[7], parent1[8], parent1[9])
        console.log(newKid);
        population.push(newKid)
        newKid=[]
        console.log(population);
    }
}
.as-console-wrapper{max-height: 100%;top: 0;}

You can also use spread syntax to create a shallow copy of the array.

let parents = [...population];

You are pushing to the same array while iterating. parents and population point to the same instance of an array. You can try creating new array while iterating.

let parents = [...population]

let population = [
  [0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
  [0, 1, 1, 1, 0, 0, 1, 1, 0, 1],
  [0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
  [0, 1, 1, 1, 0, 0, 1, 1, 0, 1],
]


kidsFactory()

function kidsFactory() {
  let newKid = []
  let parents = [...population];
  for (i = 0; i < (parents.length - 1); i++) {
    parent1 = parents[i]
    parent2 = parents[i + 1]
    console.log('parent1 ' + parent1);
    console.log('parent2 ' + parent2);
    newKid.push(parent1[0], parent1[1], parent2[2], parent2[3], parent1[4], parent1[5], parent2[6], parent2[7], parent1[8], parent1[9])
    console.log(newKid);
    population.push(newKid)
    newKid = []
    console.log(population);
  }
}

Related