//lancia un torneo su population; alla fine di tutto, ordina i pesi in population in base al migliore risultato del torneo public SortedList <WeightScore, int> LaunchTournament(SortedList <WeightScore, int> population, List <WeightsForBoardEval> testPopulation) { SortedList <WeightScore, int> newPopulation = new SortedList <WeightScore, int>(); Dictionary <WeightScore, int> scores = new Dictionary <WeightScore, int>(); for (int i = 0; i < population.Count; i++) { WeightScore ws1 = population.Keys[i]; for (int j = 0; j < testPopulation.Count; j++) { WeightsForBoardEval testPlayer = testPopulation[j]; AlphaBeta ws1AsGoose = new AlphaBeta(PawnType.Goose, 3, ws1.weights, false); AlphaBeta ws1AsFox = new AlphaBeta(PawnType.Fox, 3, ws1.weights, false); AlphaBeta ws2AsGoose = new AlphaBeta(PawnType.Goose, 3, testPlayer, false); AlphaBeta ws2AsFox = new AlphaBeta(PawnType.Fox, 3, testPlayer, false); PairOfScores pairOfScoresGoose = MatchTwoAi(ws1AsGoose, ws2AsFox, 1, i, j); PairOfScores pairOfScoresFox = MatchTwoAi(ws1AsFox, ws2AsGoose, 1, i, j); if (!scores.ContainsKey(ws1)) { scores[ws1] = 0; } scores[ws1] += pairOfScoresGoose.first; scores[ws1] += pairOfScoresFox.first; } WeightScore ws = new WeightScore(ws1.weights, scores[ws1]); newPopulation.Add(ws, scores[ws1]); } return(newPopulation); }
public int CompareTo(object obj) { WeightScore w = (WeightScore)obj; if (score <= w.score) { return(-1); } return(1); }
public void StartTest() { MatchAlgo matchAlgo = new MatchAlgo(); GeneticAlgo geneticAlgo = new GeneticAlgo(); System.Random rand = new System.Random(); List <WeightsForBoardEval> weights = new List <WeightsForBoardEval>(); for (int i = 0; i < 50; i++) { WeightsForBoardEval w = new WeightsForBoardEval(rand); weights.Add(w); Console.WriteLine("pesInizRand = " + w); } SortedList <WeightScore, int> scoreMap = new SortedList <WeightScore, int>(); //per ogni peso = giocatore, fa giocare 3 match come oca e 3 match come volpe al giocatore contro un giocatore casuale for (int i = 0; i < weights.Count; i++) { int score = 0; WeightsForBoardEval weight = weights[i]; AlphaBeta playerAsFox = new AlphaBeta(PawnType.Fox, 3, weight, false); AlphaBeta playerAsGoose = new AlphaBeta(PawnType.Goose, 3, weight, false); score = matchAlgo.MatchTwoAi(playerAsFox, null, 3, -1, -1).first; score += matchAlgo.MatchTwoAi(playerAsGoose, null, 3, -1, -1).first; WeightScore ws = new WeightScore(weight, score); scoreMap.Add(ws, score); } Console.WriteLine("aiTester prima di evoluzione"); // evolve 50 volte la popolazione for (int i = 0; i < 50; i++) { Console.WriteLine("\n \n \n \n inizio evoluzione generazione " + i); scoreMap = geneticAlgo.Evolve(scoreMap, 0.3, 0.1, 0.01); } Console.WriteLine("best weights " + scoreMap.Keys[0]); Console.WriteLine("finito completamente aiTester ore: " + DateTime.Now.ToString("h:mm:ss tt")); Console.ReadKey(); }
public SortedList <WeightScore, int> Evolve(SortedList <WeightScore, int> population, double retain, double randomSelect, double mutate) { Console.WriteLine("start genetic algo evolve"); foreach (var key in population.Keys) { Console.WriteLine(key); } System.Random rand = new System.Random(); int retainIndex = (int)(population.Count * retain); Console.WriteLine("population size = " + population.Count + " " + retain + " " + randomSelect + " " + mutate); Console.WriteLine("retain tengo " + retainIndex + " soggetti"); SortedList <WeightScore, int> parents = new SortedList <WeightScore, int>(); var iter = population.GetEnumerator(); iter.MoveNext(); for (int i = 0; i < retainIndex; i++) { parents[iter.Current.Key] = iter.Current.Value; iter.MoveNext(); } //aggiunge altri soggetti con una percentuale di aggiunta pari a randomSelect while (iter.MoveNext()) { if (randomSelect > rand.NextDouble()) { var ws = iter.Current; parents[ws.Key] = ws.Value; } } foreach (var key in parents.Keys) { Console.WriteLine(key); } int parentsCount = parents.Count; int childrenToGenerate = population.Count - parentsCount; //quanti figli devo generare per ritornare ad avere una popolazione completa int generatedChildren = 0; Console.WriteLine("fine evolve" + population.Count + " " + parents.Count + " " + childrenToGenerate); //crossover while (parents.Count < population.Count - 2) { //Console.WriteLine("parent count= " + parents.Count + " pop count = " + population.Count); //Console.WriteLine("GeneticAlgo genero figli"); int firstN = rand.Next(parentsCount); int secondN = rand.Next(parentsCount); WeightsForBoardEval male = parents.Keys[firstN].weights; WeightsForBoardEval female = parents.Keys[secondN].weights; if (!male.Equals(female)) { WeightsForBoardEval child = CrossoverAndMutate(male, female, mutate); WeightScore ws = new WeightScore(child, 0); parents[ws] = 0; generatedChildren++; } } WeightScore ws1 = new WeightScore(new WeightsForBoardEval(rand), 0); WeightScore ws2 = new WeightScore(new WeightsForBoardEval(rand), 0); parents[ws1] = 0; parents[ws2] = 0; List <WeightsForBoardEval> testPopulation = new List <WeightsForBoardEval>(); testPopulation.Add(new WeightsForBoardEval(1, 0, 0, 0, 0, 0, 0)); testPopulation.Add(new WeightsForBoardEval(2, 2, -2, -2, -1, -1, 0)); return(new MatchAlgo().LaunchTournament(parents, testPopulation)); //lancia un torneo sulla popolazione e ritorna la popolazione con gli score aggiornati }