-
Notifications
You must be signed in to change notification settings - Fork 0
/
GeneticAlgorithm.cs
147 lines (132 loc) · 5.68 KB
/
GeneticAlgorithm.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
namespace NCAABasketball
{
class GeneticAlgorithm
{
public static int trainSpeciesList(List<Species> species, int numGames)
{
// Dictionary of team name => team stats
Dictionary<String, TeamStats> teams = new Dictionary<String, TeamStats>();
int predictableGames = 0;
int speciesLength = species.Count();
// for every game
for (int i = 1; i <= numGames; i++)
{
String[] games = GameFileReader.getGameInfoArray(i); // Each array value is a string of stats for 1 game
String teamName1 = TeamStats.getNameFromGameInfo(games[0]);
String teamName2 = TeamStats.getNameFromGameInfo(games[1]);
// if 1 team not in hashtable, add to hashtable and update both teams
if (!teams.ContainsKey(teamName1) || !teams.ContainsKey(teamName2))
{
if (!teams.ContainsKey(teamName1))
{
teams.Add(teamName1, new TeamStats());
}
if (!teams.ContainsKey(teamName2))
{
teams.Add(teamName2, new TeamStats());
}
teams[teamName1].updateStats(games[0]);
teams[teamName2].updateStats(games[1]);
continue; // Immediately go to next game
}
// If we get here, both teams exist in the hashtable (which is a Dictionary in c#)
predictableGames++;
List<int> predictVector = new List<int>();
for (int j = 0; j < speciesLength; j++)
{
// Evaluate prediction of 1 or 2 and add to prediction vector
predictVector.Add(species[j].Predict(teams[teamName1], teams[teamName2]));
}
// Evaluate real result (consequently updating both teams)
teams[teamName1].updateStats(games[0]);
teams[teamName2].updateStats(games[1]);
int correctPrediction = 2; // Defalt to pick 2 just to reduce to 1 if statement
if (teams[teamName1].lastGameScore() > teams[teamName2].lastGameScore()) // Don't think you can tie but it would be akward to see this not work
{
correctPrediction = 1;
teams[teamName1].win();
teams[teamName2].lose();
}
else
{
teams[teamName2].win();
teams[teamName1].lose();
}
// For every species
for (int j = 0; j < speciesLength; j++)
{
if (predictVector[j] == correctPrediction)
{
// If specie predicted correctly, update fitness
species[j].correctPrediction();
}
}
}
return predictableGames; // Returns number of predictable games, good to know
}
public static List<Species> speciesUpdate(int nBest, List<Species> speciesList, Random rnd)
{
List<Species> newSpeciesList = new List<Species>();
int listSize = speciesList.Count();
// Sort species list of size l
speciesList.Sort();
speciesList.Reverse(); // Can switch to descending if too computationally inefficient to reverse list
// Take n best results
for (int i = 1; i <= nBest; i++)
{
speciesList[i-1].resetFitness(); // Reset fitnesses even though just going to recalculate
newSpeciesList.Add(speciesList[i-1]);
}
// Create l-n mutations of n species
for (int i = nBest; i < listSize; i++)
{
// First choose which of nBest to modify
int nSpecie = rnd.Next(0, nBest);
// Add mutation of that specie
newSpeciesList.Add(new Species(newSpeciesList[nSpecie].getOp().mutate(rnd)));
}
return newSpeciesList;
}
public static List<Species> generateInitialSpeciesList(int size, Random rnd)
{
List<Species> speciesList = new List<Species>();
// Create initial list with species with constant values
for (int i = 0; i < size; i++)
{
speciesList.Add(new Species(Constant.generateInitialConstant(rnd)));
}
return speciesList;
}
public static void printStats(List<Species> speciesList)
{
// Have to go through all species to get mean
int length = speciesList.Count();
int total = 0;
for (int i = 0; i < length; i++)
{
total += speciesList[i].getNumCorrect();
}
double mean = System.Convert.ToDouble(total) / System.Convert.ToDouble(length);
Species max = speciesList.Max();
Species min = speciesList.Min();
Console.WriteLine("MAX: " + max);
Console.WriteLine("MIN: " + min);
Console.WriteLine("MEAN: " + mean);
}
public static void printNSorted(int n, List<Species> speciesList)
{
speciesList.Sort();
speciesList.Reverse();
for (int i = 0; i < n; i++)
{
Console.WriteLine(speciesList[i]);
}
}
}
}