func Run(conf Config) error { rand.Seed(time.Now().UTC().UnixNano()) fmt.Println("Loading proteins...") id, start, end, err := db.GetProteins(conf.DB) if err != nil { panic(err) } fmt.Println("Initializing probabilities...") r, _ := rules.Create(conf.CA.InitStates, conf.CA.TransStates, conf.CA.HasJoker, conf.CA.R) probs := NewProbs(r.Prm) var pop Population pop.rule = make([]*rules.Rule, conf.Design.Population) pop.fitness = make([]float64, conf.Design.Population) pop.rule[0], _ = rules.Create(conf.CA.InitStates, conf.CA.TransStates, conf.CA.HasJoker, conf.CA.R) cellauto, _ := ca.Create1D(id, start, end, pop.rule[0], conf.CA.Steps, conf.CA.Consensus) pop.fitness[0] = Fitness(cellauto) for i := 1; i < conf.Design.Population; i++ { pop.rule[i] = probs.GenRule() cellauto.SetRule(pop.rule[i]) pop.fitness[i] = Fitness(cellauto) } pop.save("") return nil }
func TestCreate1D(t *testing.T) { // teste caso 1 id := tests[0].id begin := tests[0].begin end := tests[0].expected rule, _ := rules.Create(begin, end, true, 3) ca, err := Create1D(id, begin, end, rule, 10) if err != nil { t.Error("Caso 1. Erro na criação do autômato celular") } if ca == nil { t.Error("Caso 1. Erro no retorno do autômato celular") } // teste caso 2 id = tests[1].id begin = tests[1].begin end = tests[1].expected rule, _ = rules.Create(begin, end, true, 3) ca, err = Create1D(id, begin, end, rule, 19) if err == nil { t.Error("Caso 2. Erro na criação do autômato celular que não capturou o erro. ") } if ca != nil { t.Error("Caso 2. Erro no retorno do autômato celular que retornou um autômato inválido") } }
func TestGenRule(t *testing.T) { rule, _ := rules.Create(rules.PrmDefault) p := NewProbs(rule.Prm) ruleNew1 := p.GenRule() ruleNew2 := p.GenRule() fmt.Println("@@@Nova regra (1)", ruleNew1) fmt.Println("@@@Nova regra (2)", ruleNew2) }
// func Run(selby string, fnrulein string, fnruleout string, fnprobout string, gen int, pop int, steps int, ca *ca.CellAuto1D, prm rules.Params) error { func Run(conf Config) error { rand.Seed(time.Now().UTC().UnixNano()) fmt.Println("Loading proteins...") id, start, end, err := db.GetProteins(conf.DB) if err != nil { panic(err) } fmt.Println("Initializing probabilities...") rule, _ := rules.Create(conf.CA.InitStates, conf.CA.TransStates, conf.CA.HasJoker, conf.CA.R) probs := NewProbs(rule.Prm) fmt.Println(probs) var calist []*ca.CellAuto1D calist = make([]*ca.CellAuto1D, conf.CGA.Selection) for i := 0; i < len(calist); i++ { r := probs.GenRule() calist[i], _ = ca.Create1D(id, start, end, r, conf.CA.Steps, conf.CA.Consensus) } var wg1 sync.WaitGroup for i := 0; i < conf.CGA.Generations; i++ { fmt.Println("Generation", i) fmt.Println("Adjusting probabilities...") probs.AdjustByRanking(calist, 1.0/float64(conf.CGA.Population)) fmt.Println("OK") if probs.Converged() { fmt.Println("Probabilities converged\nDONE") break } for i := 0; i < len(calist); i++ { wg1.Add(1) go func(i int) { defer wg1.Done() calist[i].SetRule(probs.GenRule()) }(i) // calist[i], _ = ca.Create1D(id, start, end, r, conf.CA.Steps) } fmt.Printf("Waiting ") wg1.Wait() fmt.Println("OK") } err = ioutil.WriteFile(conf.CGA.OutputProbs, []byte(probs.String()), 0644) if err != nil { fmt.Println("Erro gravar as probabilidades") fmt.Println(probs) } return nil }
func Run(conf Config) error { rand.Seed(time.Now().UTC().UnixNano()) fmt.Println("Loading proteins...") id, start, end, err := proteindb.GetProteins(conf.ProteinDB) if err != nil { panic(err) } fmt.Println("Initializing simulated annealing") rule, _ := rules.Create(conf.CA.InitStates, conf.CA.TransStates, conf.CA.HasJoker, conf.CA.R) cellauto, _ := ca.Create1D(id, start, end, rule, conf.CA.Steps, conf.CA.Consensus) solution := &Solution{rule, Fitness(cellauto)} solution_new := &Solution{rule, Fitness(cellauto)} solution_best := &Solution{rule, Fitness(cellauto)} alpha := math.Pow((conf.SA.Tfinal / conf.SA.Tini), 1.0/float64(conf.SA.OuterLoop)) temp := conf.SA.Tini for outer := 0; outer < conf.SA.OuterLoop; outer++ { fmt.Println("@ Temperature", temp) for inner := 0; inner < conf.SA.InnerLoop; inner++ { solution_new.Neighbor(solution) cellauto.SetRule(solution_new.rule) solution_new.fitness = Fitness(cellauto) if solution_new.fitness >= solution.fitness { fmt.Println("Update", solution.fitness, "->", solution_new.fitness) solution.rule = solution_new.rule solution.fitness = solution_new.fitness //fmt.Println("Check update", solution.fitness, "=", solution_new.fitness) if solution.fitness > solution_best.fitness { fmt.Println("Update BEST", solution_best.fitness, "->", solution.fitness) solution_best.rule = solution.rule solution_best.fitness = solution.fitness } } else if math.Exp(solution_new.fitness-solution.fitness/temp) > rand.Float64() { fmt.Println("*Update", solution.fitness, "->", solution_new.fitness) solution.rule = solution_new.rule solution.fitness = solution_new.fitness //fmt.Println("*Check update", solution.fitness, "=", solution_new.fitness) } } temp = alpha * temp } err = ioutil.WriteFile(conf.Rules.Output, []byte(solution_best.rule.String()), 0644) if err != nil { fmt.Println("Erro gravar a melhor regra") fmt.Println(solution_best.rule) } fmt.Println("Melhor regra", solution_best.fitness) return nil }
func TestAdjustByDuel(t *testing.T) { rule, _ := rules.Create(rules.PrmDefault) p := NewProbs(rule.Prm) fmt.Println(p) r1 := p.GenRule() r2 := p.GenRule() p.AdjustByDuel(r1, r2) for i := 0; i < 1000; i++ { r1 = p.GenRule() r2 = p.GenRule() p.AdjustByDuel(r1, r2) fmt.Println("Geração ", i) fmt.Println(p) } }
func RunSlave(conf Config) { // Cria o receptor que recebe a probabilidade emitida pelo master na porta A receiver, _ := zmq.NewSocket(zmq.PULL) defer receiver.Close() receiver.Connect("tcp://" + conf.Dist.MasterURL + ":" + conf.Dist.PortA) // Cria o emissor que envia o individuo vencedor do torneio na rede pela // porta B sender, _ := zmq.NewSocket(zmq.PUSH) defer sender.Close() sender.Connect("tcp://" + conf.Dist.MasterURL + ":" + conf.Dist.PortB) // semente randomica rand.Seed(time.Now().UTC().UnixNano()) // Le os dados das proteinas no DB fmt.Println("Loading proteins...") id, start, end, err := db.GetProteins(conf.DB) if err != nil { fmt.Println("Erro no banco de DADOS") panic(err) } fmt.Println("Done") // ? Ha vantagem em enviar um sinal de Ok (proteinas lidas) para o master? var prob Probabilities var tourn Tournament tourn = make([]Individual, conf.EDA.Tournament) // tourn.rule = make([]*rules.Rule, conf.EDA.Tournament) // tourn.fitness = make([]float64, conf.EDA.Tournament) r, _ := rules.Create(conf.CA.InitStates, conf.CA.TransStates, conf.CA.HasJoker, conf.CA.R) // probabilidade temporaria para ser substituida pelas recebidas p_tmp := NewProbs(r.Prm) cellAuto := make([]*ca.CellAuto1D, conf.EDA.Tournament) for i := 0; i < conf.EDA.Tournament; i++ { // tourn.rule[i] = p_tmp.GenRule() tourn[i].Rule = p_tmp.GenRule() // cellAuto[i], _ = ca.Create1D(id, start, end, tourn.rule[i], conf.CA.Steps, conf.CA.Consensus) cellAuto[i], _ = ca.Create1D(id, start, end, tourn[i].Rule, conf.CA.Steps, conf.CA.Consensus) } // Individuo vencedor do torneio var ( ind Individual b []byte m string conerr error ) for { // m é a mensagem com as probabilidades m, conerr = receiver.Recv(0) // m, err := conn.Request(conf.Dist.TopicFromMaster, []byte("get"), 2*time.Second) if conerr == nil { // para cada individuo no torneio // gera uma regra de acordo com a probabilidade atual // roda o automato celular // calcula o fitness // seleciona o vencedor do torneio // retorna sua regra e seu fitness) // converte a probabilidade recebida em JSON para uma estrutura json.Unmarshal([]byte(m), &prob) fmt.Printf("PID: %d, Geracacao: %d\n", prob.PID, prob.Generation) // for i := 0; i < len(tourn.rule); i++ { for i := 0; i < len(tourn); i++ { // copia a probabilidade recebida para a probabilidade dos individuos copy(p_tmp.probs, prob.Data) // gera a regra e atribui ao membro do torneio tourn[i].Rule = p_tmp.GenRule() // define a regra do automato como sendo a nova regra cellAuto[i].SetRule(tourn[i].Rule) // retorna o fitness e outras medidas de desempenho do autômato tourn[i].Fitness, tourn[i].Q3 = FitnessAndQ3(cellAuto[i]) // fmt.Println("Individuo", i, "Fitness", tourn.fitness[i]) fmt.Println("Individuo", i, "Fitness", tourn[i].Fitness) } // Ordena os individuos do torneio de acordo com o fitness (maior primeiro) sort.Sort(sort.Reverse(tourn)) // ind.PID, ind.Generation, ind.Rule, ind.Fitness = prob.PID, prob.Generation, tourn.rule[0], tourn.fitness[0] ind.PID, ind.Generation, ind.Rule, ind.Fitness, ind.Q3 = prob.PID, prob.Generation, tourn[0].Rule, tourn[0].Fitness, tourn[0].Q3 // Codifica o individuo vencedor em JSON e envia para o master b, _ = json.Marshal(ind) fmt.Println("Fitness selecionado", tourn[0].Fitness) sender.Send(string(b), 0) } else { // Erro na conexão fmt.Println(err) } } }
func Run(conf Config) error { rand.Seed(time.Now().UTC().UnixNano()) fmt.Println("Loading proteins...") id, start, end, err := proteindb.GetProteins(conf.ProteinDB) if err != nil { panic(err) } fmt.Println("Initializing probabilities...") r, _ := rules.Create(conf.CA.InitStates, conf.CA.TransStates, conf.CA.HasJoker, conf.CA.R) probs := NewProbs(r.Prm) // fmt.Println(probs) var pop Population pop.rule = make([]*rules.Rule, conf.EDA.Population) pop.fitness = make([]float64, conf.EDA.Population) cellAuto := make([]*ca.CellAuto1D, conf.EDA.Population) var wg1 sync.WaitGroup // tmp := 0 for i := 0; i < conf.EDA.Population; i++ { wg1.Add(1) go func(pop *Population, i int) { defer wg1.Done() pop.rule[i] = probs.GenRule() // ca, _ := ca.Create1D(id, start, end, pop.rule[i], conf.CA.Steps, conf.CA.Consensus) cellAuto[i], _ = ca.Create1D(id, start, end, pop.rule[i], conf.CA.Steps, conf.CA.Consensus) pop.fitness[i] = Fitness(cellAuto[i]) }(&pop, i) //preciso definir o que por aqui if i%48 == 0 && i > 0 { fmt.Println("Waiting", i) wg1.Wait() } } wg1.Wait() fmt.Println("População inicial = ", conf.EDA.Population, "OK") // tmp := make([]float64, len(pop.fitness)) // for j := range tmp { // tmp[j] = pop.fitness[j] * 1.1 // } var wg2 sync.WaitGroup for i := 0; i < conf.EDA.Generations; i++ { fmt.Println("Generation", i+1) fmt.Println("Adjusting probabilities...") probs.AdjustProbs(pop, conf.EDA.Selection, conf.EDA.Tournament) fmt.Println("OK") if probs.Converged() { fmt.Println("Probabilities converged\nDONE") break } if (i+1)%conf.EDA.SaveSteps == 0 { ioutil.WriteFile(fmt.Sprintf("%s_%d", conf.EDA.OutputProbs, i+1), []byte(probs.String()), 0644) } for j := 0; j < len(pop.rule); j++ { wg2.Add(1) go func(pop *Population, j int) { defer wg2.Done() pop.rule[j] = probs.GenRule() // ca, _ := ca.Create1D(id, start, end, pop.rule[j], conf.CA.Steps, conf.CA.Consensus) cellAuto[j].SetRule(pop.rule[j]) pop.fitness[j] = Fitness(cellAuto[j]) }(&pop, j) if j%24 == 0 && j > 0 { fmt.Println("Waiting", j) wg2.Wait() } } fmt.Printf("Wait - Setting new rule") wg2.Wait() fmt.Println("OK") //Este é o melhor lugar para criar o grafico? pop plot.Histogram(pop.fitness, nil, i) } err = ioutil.WriteFile(conf.EDA.OutputProbs, []byte(probs.String()), 0644) if err != nil { fmt.Println("Erro gravar as probabilidades") fmt.Println(probs) } return nil }
func RunMaster(conf Config) { // cria o emissor que envia as probabilidades para toda a rede na porta A sender, _ := zmq.NewSocket(zmq.PUSH) defer sender.Close() sender.Bind("tcp://*:" + conf.Dist.PortA) // cria o receptor que recebe os individuos de toda a rede na porta B receiver, _ := zmq.NewSocket(zmq.PULL) defer receiver.Close() receiver.Bind("tcp://*:" + conf.Dist.PortB) // gerar (ou ler -> TODO) as probabilidades iniciais r, _ := rules.Create(conf.CA.InitStates, conf.CA.TransStates, conf.CA.HasJoker, conf.CA.R) p := NewProbs(r.Prm) // a população do DistEDA será de apenas vencedores dos torneios locais, // realizados nos slaves. Portanto, população é igual população/n_torneio var pop []Individual pop = make([]Individual, conf.EDA.Population/conf.EDA.Tournament) popFitness := make([]float64, conf.EDA.Population/conf.EDA.Tournament) popQ3 := make([]float64, conf.EDA.Population/conf.EDA.Tournament) // cria um arquivo de log onde serão salvas as estatisticas por geração, como // média e variância do Q3 fstat, err := os.Create("log") if err != nil { panic(err) } defer fstat.Close() // os slaves demoram um pouco para inicializar pois precisam acessar o DB e // carregar os dados. O master precisa esperar os slaves estarem prontos. Por // enquanto, o sinal de inicio é dado manualmente (TODO -> pensar numa forma // automática) fmt.Print("Press Enter when the workers are ready: ") var line string fmt.Scanln(&line) fmt.Println("Sending tasks to workers...") // Inicio do processamento fmt.Println("RUNNING MASTER") // para cada geracao for g := 0; g < conf.EDA.Generations; g++ { fmt.Println("GERACAO", g) // atualizar as probabilidades de acordo com a populacao dessa geracao if g != 0 { // TODO refazer a funcao para trabalhar com toda a populacao. Acho que // esta feito. Confirmar!!! p.AdjustProbs(pop) } // Criar as probabilidades para serem enviadas no formato JSON. // Será enviado o ID (PID) = hash da probabilidade, o número da geração e as // probabilidades tmp, _ := json.Marshal(p.probs) pid := adler32.Checksum(tmp) prob := &Probabilities{PID: pid, Generation: g, Data: p.probs} b, _ := json.Marshal(prob) // Para cada individuo que precisará retornar deve ser emitida uma // probabilidade. Uma goroutine fica emitindo probabilidades que vão sendo // capturados pelos slaves que após o torneio, devolvem o vencedor go func(b *[]byte) { for i := 0; i < len(pop); i++ { sender.Send(string(*b), 0) } }(&b) // Capta os individuos vencedores gerados pelos slaves for i := 0; i < len(pop); { m, err := receiver.Recv(0) if err == nil { json.Unmarshal([]byte(m), &pop[i]) // Checa pelo ID da probabilidade se o individuo vencedor que chegou foi // gerado pela última probabilidade que foi emitida if prob.PID == pop[i].PID { // fmt.Printf("Individuo id: %d rid: %d g: %d, score: %f\n", g*len(pop)+i, pop[i].PID, pop[i].Generation, pop[i].Fitness) popFitness[i] = pop[i].Fitness popQ3[i] = pop[i].Q3 i++ } else { fmt.Println(prob.PID, pop[i].PID) } } else { fmt.Println(err) } } // IMPORTANTE // TODO criar um mecanismo para contornar falhas nos nós // imprimir e as estatisticas// salva as probabilidades a cada geração err := ioutil.WriteFile(conf.EDA.OutputProbs+"_g"+strconv.Itoa(g), []byte(p.String()), 0644) if err != nil { fmt.Println("Erro gravar as probabilidades") fmt.Println(p) } // imprimir e as estatisticas meanFit, stdFit := stat.MeanStdDev(popFitness, nil) meanQ3, stdQ3 := stat.MeanStdDev(popQ3, nil) fstat.WriteString(fmt.Sprintf("G: %d, Mean: %.5f, StdDev: %.5f, Mean Q3: %.5f, StdDev Q3: %.5f, \n", g, meanFit, stdFit, meanQ3, stdQ3)) fmt.Printf("G: %d, Mean: %.5f, StdDev: %.5f, Mean Q3: %.5f, StdDev Q3: %.5f, \n", g, meanFit, stdFit, meanQ3, stdQ3) } // salvar a melhor regra }
func Run(conf Config) error { rand.Seed(time.Now().UTC().UnixNano()) fmt.Println("Loading proteins...") id, start, end, err := proteindb.GetProteins(conf.ProteinDB) if err != nil { panic(err) } var pop Population pop.rule = make([]*rules.Rule, conf.GA.Population) pop.fitness = make([]float64, conf.GA.Population) var wg1 sync.WaitGroup // tmp := 0 for i := 0; i < conf.GA.Population; i++ { wg1.Add(1) go func(pop *Population, i int) { defer wg1.Done() pop.rule[i], _ = rules.Create(conf.CA.InitStates, conf.CA.TransStates, conf.CA.HasJoker, conf.CA.R) ca, _ := ca.Create1D(id, start, end, pop.rule[i], conf.CA.Steps, conf.CA.Consensus) pop.fitness[i] = Fitness(ca) }(&pop, i) //preciso definir o que por aqui if i%100 == 0 && i > 0 { fmt.Println("Waiting", i) wg1.Wait() } } wg1.Wait() var selection Selection selection.rule = make([]*rules.Rule, conf.GA.Selection) selection.fitness = make([]float64, conf.GA.Selection) // var tournament Tournament // tournament.rule = make([]*rules.Rule, conf.GA.Tournament) // tournament.fitness = make([]float64, conf.GA.Tournament) var wg2 sync.WaitGroup for i := 0; i < conf.GA.Generations; i++ { fmt.Println("Gen", i) sort.Sort(sort.Reverse(pop)) for j := 0; j < conf.GA.Selection; j++ { winner := len(pop.rule) for k := 0; k < conf.GA.Tournament; k++ { x := rand.Intn(len(pop.rule)) if x < winner { winner = x } } //sort.Sort(sort.Reverse(tournament)) selection.rule[j] = pop.rule[winner] selection.fitness[j] = pop.fitness[winner] } fmt.Println("Selection OK") plot.Histogram(pop.fitness, selection.fitness, i) fmt.Println("Plot", i, "ok") for p := 0; p < len(pop.rule); p++ { wg2.Add(1) go func(pop *Population, p int) { defer wg2.Done() s := rand.Intn(len(selection.rule)) Mutate(selection.rule[s], conf.GA.Mutation) pop.rule[p] = selection.rule[s] ca, _ := ca.Create1D(id, start, end, pop.rule[p], conf.CA.Steps, conf.CA.Consensus) pop.fitness[p] = Fitness(ca) }(&pop, p) if p%10 == 0 && p > 0 { fmt.Println("Waiting", p) wg2.Wait() } } fmt.Println("New pop OK") } return nil }