Advertisement
Guest User

Untitled

a guest
Jan 31st, 2016
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.83 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4.  
  5. namespace ml
  6. {
  7. public class Citizen
  8. {
  9. private static int _nextId = 0;
  10.  
  11. public int Id { get; private set; }
  12. public int Fitness { get; private set; }
  13. public string Value { get; set; }
  14.  
  15. // Not necessary, but fun...
  16. public Citizen Mother { get; set; }
  17. public Citizen Father { get; set; }
  18.  
  19. public Citizen()
  20. {
  21. Id = _nextId;
  22. _nextId++;
  23.  
  24. Fitness = int.MaxValue;
  25. Value = "";
  26.  
  27. Mother = null;
  28. Father = null;
  29. }
  30.  
  31. public override string ToString()
  32. {
  33. return string.Format("Id: {0:D6}, Value: {1}, Fitness: {2:D4}, Mother: {3:D6}, Father: {4:D6}",
  34. Id, Value, Fitness, (Mother == null) ? 0 : Mother.Id, (Father == null) ? 0 : Father.Id);
  35. }
  36.  
  37. public void SetFitnessToTarget(string target)
  38. {
  39. int fitness = 0;
  40.  
  41. for (int i = 0; i < target.Length; i++)
  42. {
  43. int difference = target[i] - Value[i];
  44. fitness += Math.Abs(difference);
  45. }
  46.  
  47. Fitness = fitness;
  48. }
  49. }
  50.  
  51. public class Simulation
  52. {
  53. private readonly string POSSIBLE_CHARACTERS = " `1234567890-=qwertyuiop[]\\asdfghjkl;'zxcvbnm,./~!@#$%^&*()_+QWERTYUIOP{}|ASDFGHJKL:\"ZXCVBNM<>?";
  54.  
  55. private List<Citizen> m_population;
  56. private Random m_random = new Random();
  57. private string m_target = "";
  58. private int m_populationSize = 0;
  59. private double m_mutationRate = 0.0;
  60. DateTime m_startTime;
  61. DateTime m_endTime;
  62.  
  63. public Simulation(string target, int populationSize, double mutationRate)
  64. {
  65. m_target = target;
  66. m_populationSize = populationSize;
  67. m_mutationRate = mutationRate;
  68. m_population = new List<Citizen>(populationSize);
  69.  
  70. Console.WriteLine("Target: {0}, Population Size: {1}, Mutation Rate: {2}", target, populationSize, mutationRate);
  71.  
  72. // The first generation. About the same intelligence as most politicians...
  73. for (int i = 0; i < populationSize; i++)
  74. {
  75. Citizen c = new Citizen();
  76. c.Value = GenerateRandomString(target.Length);
  77. m_population.Add(c);
  78. }
  79. }
  80.  
  81. void CalculateTheFitnessOfTheCitizens()
  82. {
  83. m_population.ForEach((c) => { c.SetFitnessToTarget(m_target); });
  84. }
  85.  
  86. void SortThePopulationByFitness()
  87. {
  88. m_population.Sort((left, right) => left.Fitness.CompareTo(right.Fitness));
  89. }
  90.  
  91. void RemoveTheWeakestCitizens()
  92. {
  93. m_population.RemoveRange(m_populationSize / 2, m_populationSize / 2);
  94. }
  95.  
  96. string GenerateRandomString(int length)
  97. {
  98. StringBuilder sb = new StringBuilder(length);
  99.  
  100. for (int i = 0; i < length; i++)
  101. {
  102. sb.Append(POSSIBLE_CHARACTERS[m_random.Next(POSSIBLE_CHARACTERS.Length)]);
  103. }
  104.  
  105. return sb.ToString();
  106. }
  107.  
  108. void ApplyRandomMutation(ref StringBuilder value)
  109. {
  110. value[m_random.Next(value.Length)] = POSSIBLE_CHARACTERS[m_random.Next(POSSIBLE_CHARACTERS.Length)];
  111. }
  112.  
  113. void GetRandomParents(out Citizen mother, out Citizen father)
  114. {
  115. int a = m_random.Next(m_population.Count);
  116. int b = m_random.Next(m_population.Count);
  117.  
  118. while (b == a) //Don't allow the same parent for both
  119. {
  120. b = m_random.Next(m_population.Count);
  121. }
  122.  
  123. mother = m_population[a];
  124. father = m_population[b];
  125. }
  126.  
  127. Citizen Mate(Citizen mother, Citizen father)
  128. {
  129. StringBuilder newValue = new StringBuilder();
  130. Citizen child = new Citizen();
  131.  
  132. child.Mother = mother;
  133. child.Father = father;
  134.  
  135. for (int i = 0; i < mother.Value.Length; i++)
  136. {
  137. // Determine dominant features randomly
  138. bool fatherIsDominant = m_random.NextDouble() < .5;
  139.  
  140. if (fatherIsDominant)
  141. newValue.Append(father.Value[i]);
  142. else
  143. newValue.Append(mother.Value[i]);
  144. }
  145.  
  146. double chanceOfMutation = m_random.NextDouble();
  147. if (chanceOfMutation < m_mutationRate)
  148. ApplyRandomMutation(ref newValue);
  149.  
  150. child.Value = newValue.ToString();
  151.  
  152. return child;
  153. }
  154.  
  155. void MateThePopulation()
  156. {
  157. var parents = m_population;
  158. var children = new List<Citizen>(m_populationSize);
  159.  
  160. for (int i = 0; i < m_populationSize; i++)
  161. {
  162. Citizen mother = null;
  163. Citizen father = null;
  164.  
  165. GetRandomParents(out mother, out father);
  166.  
  167. var child = Mate(mother, father);
  168.  
  169. children.Add(child);
  170. }
  171.  
  172. m_population = children; //Children are the future...
  173. }
  174.  
  175. void PrintPaternalLineage(Citizen c)
  176. {
  177. Citizen father = c.Father;
  178. Console.Write("{0} ", c.Id);
  179. while (father != null)
  180. {
  181. Console.Write("=> {0} ", father.Id);
  182. father = father.Father;
  183. }
  184. Console.WriteLine();
  185. }
  186.  
  187. public void Run(int maxGenerations)
  188. {
  189. Console.WriteLine("Starting simulation");
  190. m_startTime = DateTime.Now;
  191.  
  192. for (int i = 0; i < maxGenerations; i++)
  193. {
  194. CalculateTheFitnessOfTheCitizens();
  195. SortThePopulationByFitness();
  196.  
  197. var fittest = m_population[0];
  198.  
  199. Console.WriteLine("[Gen {0:D5}] {1}", i, fittest);
  200.  
  201. // Game over...
  202. if (fittest.Fitness == 0)
  203. {
  204. m_endTime = DateTime.Now;
  205. Console.WriteLine();
  206. Console.WriteLine("Perfection reached after {0} generations. Time elapsed: {1}", i, (m_endTime - m_startTime).ToString());
  207. Console.WriteLine();
  208. PrintPaternalLineage(fittest);
  209. break;
  210. }
  211.  
  212. RemoveTheWeakestCitizens();
  213. MateThePopulation();
  214. }
  215. }
  216. }
  217.  
  218. class Program
  219. {
  220. static void Main(string[] args)
  221. {
  222. Simulation s = new Simulation(
  223. target: "Genetic algorithms are cool!",
  224. populationSize: 2048,
  225. mutationRate: 0.25);
  226.  
  227. s.Run(maxGenerations: 100);
  228.  
  229. Console.WriteLine("Press any key...");
  230. Console.ReadKey();
  231. }
  232. }
  233. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement