1
\$\begingroup\$

I learnt a little about genetic algorithm. And I made a program from typescript that tries to evolve and match word/sentence using genetic algorithm. But if I give a little longer sentence it takes 2000+ generation to evolve and match the sentence.

I have two classes, one class called nature that generates population, natural selection, calculate fitness etc. another class called Member that has genes and do crossover and mutation.

Here is Nature.ts:

import { Member } from  "./genes";
import { AudioContext } from "web-audio-api"
function arraysEqual(a1: Array<any>,a2: Array<any>) {
    return JSON.stringify(a1)==JSON.stringify(a2);
}
const context = new AudioContext()

class Nature {
    private population: Array<Member>
    private n: number
    private matingPool: Array<Member>
    private selected: Array<Member>
    private newPopulation: Array<Member>
    private generation_count: number
    constructor(private target: string, private n_population: number, private mutation_rate: number){
        this.population = [];
        this.n = target.length;
        this.matingPool = [];
        this.selected = [];
        this.newPopulation = [];
        this.generation_count = 0;
    }
    public init(){
        this.calcFitness()
        this.naturalSelection()
        this.print()
        this.mate()   
    }
    public generatePopulation(){
        for(let i  = 1; i<=this.n_population; i++){
            this.population.push(new Member(this.n))
        }
    }
    private calcFitness(){
        for(let member of this.population){
            const gene = member.gene;
            for(let i = 0; i<this.n; i++){
                if(gene[i] === this.target[i]){
                    member.score += 1
                }
            }
        }
    }
    private naturalSelection(){
        for(let member of this.population){
            for(let i = 1; i<member.score; i++){
                this.matingPool.push(member)
            }
        }
        for(let i = 1; i<=2; i++){
            const rand = Math.floor(Math.random()*this.matingPool.length)
            this.selected.push(this.matingPool[rand])
        }
    }

    private mate(){
        this.newPopulation = []
        for(let i = 0; i<this.n_population; i++){
            const parent1 = this.selected[0]
            const parent2 = this.selected[1]
            const child = parent1.crossover(parent2)
            // console.log(child.gene.toString().replace(",", "").replace(", ", " "))
            if(arraysEqual(child.gene, this.target.split(""))){
                console.log(child.gene)
                return
            }
            this.newPopulation.push(child)
        }
        this.updateGeneration()
    }

    private updateGeneration(){
        this.population = this.newPopulation
        this.matingPool = []
        this.selected = []
        this.newPopulation = []
        this.generation_count++
        console.log('\x1b[36m%s\x1b[0m', `generation ${this.generation_count}`);
        this.init()
    }

    public print(){

    }
}

const nature = new Nature("to be or ", 200,  0.1)
nature.generatePopulation()
nature.init()

Here is Member.ts:

export class Member {
    public gene: Array<string>
    public score: number
    constructor(private n: number){
        const strings = "abcdefghijklmnopqrstuvwxyz   "
        this.gene = []
        this.score = 0;
        for(let i = 0; i<n; i++){
            const random = Math.floor(Math.random()*strings.length)
            this.gene.push(strings.charAt(random))
        }
    }
    private getRandomChar(){
        const strings = "abcdefghijklmnopqrstuvwxyz   "
        const random = Math.floor(Math.random()*strings.length)
        return strings.charAt(random)
    }
    public addGene(data: string){
        this.gene.push(data)
    }
    public crossover(partner: Member){
        const partner_gene = partner.gene;
        const gene = this.gene;
        const rand = Math.floor(Math.random()*(gene.length+1))-1
        const child = new Member(this.n)
        child.gene = []
        for(let i = 0; i<gene.length; i++){
            if(i<rand){
                child.addGene(gene[i])
            }else{
                child.addGene(partner_gene[i])
            }
        }
        child.mutate(25)
        return child
    }
    public mutate(rate: number){
        const mutation_rate = Math.random() * 100
        if(mutation_rate  <= rate ){
            const mutate_pos = Math.floor(Math.random()*this.gene.length)
            this.gene[mutate_pos] = this.getRandomChar()
        }
    }
}

\$\endgroup\$
1
  • \$\begingroup\$ Please remove the very last paragraph because we do not recommend projects here, we just review the code if it works. \$\endgroup\$ Jul 16 at 9:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.