func makeRandomPopulation(size int, accountId int64, originalPerson *database.Person) (pop *Population) { db := database.OpenDB() defer db.Close() pop = &Population{} genomes := make([]*Genome, size) for i := 0; i < size; i++ { // seed with the original person persMap := make(map[string]*database.Person) persMap[originalPerson.MonetateId] = originalPerson // seed with the original person's products prodMap := make(map[string]*database.Product) // TODO: Don't requery for every genome products := database.QueryProductsViewedAndPurchased(db, accountId, originalPerson) for i := 0; i < len(products); i++ { prodMap[products[i].Pid] = products[i] } rs := &RecoSet{products: prodMap, people: persMap} genome := &Genome{rs: rs, score: 0.0} genome.addRandomTrait() genomes[i] = genome } pop.genomes = genomes return }
func (pop *Population) evolve(maxPopulation int, maxGenerations int, accountId int64, originalPerson *database.Person) { db := database.OpenDB() defer db.Close() for g := 0; g < maxGenerations; g++ { fmt.Printf("processing generation %d\n", g) ch := make(chan bool) for i := 0; i < len(pop.genomes); i++ { go func(ch chan bool, genome *Genome) { // apply the update of the last (current) trait a genome genome.getCurrentTrait().update(db, genome.rs, accountId, originalPerson) genome.checkFitness(db, accountId, originalPerson) ch <- true }(ch, pop.genomes[i]) } // drain the channel for i := 0; i < len(pop.genomes); i++ { <-ch } pop.display() if g == (maxGenerations - 1) { pop.displayFinal() } else { // select genomes to carry forward to the next generation pop.makeSelection() // add new traits to the surviving genomes for i := 0; i < len(pop.genomes); i++ { pop.genomes[i].addRandomTrait() } // have the successful ones reproduce to fill out the remainder of the population childrenGenomes := make([]*Genome, 0) for i := 0; i < (maxPopulation - len(pop.genomes)); i++ { r1 := rand.Intn(len(pop.genomes)) r2 := rand.Intn(len(pop.genomes)) newGenome := reproduce(pop.genomes[r1], pop.genomes[r2]) childrenGenomes = append(childrenGenomes, newGenome) } pop.appendGenomes(childrenGenomes) } } }