Repository where I mostly put random python scripts.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

253 lines
7.4 KiB

  1. <html>
  2. <head>
  3. <script>
  4. class Gene
  5. {
  6. constructor(min, max, value)
  7. {
  8. this.min = min;
  9. this.max = max;
  10. this.value = value;
  11. }
  12. getRealValue()
  13. {
  14. return (this.max - this.min) * this.value + this.min;
  15. }
  16. getValue()
  17. {
  18. return this.value;
  19. }
  20. setValue(val)
  21. {
  22. this.value = val;
  23. }
  24. makeClone()
  25. {
  26. return new Gene(this.min, this.max, this.value);
  27. }
  28. makeRandomGene()
  29. {
  30. return new Gene(this.min, this.max, Math.random());
  31. }
  32. }
  33. class Chromosome
  34. {
  35. constructor(geneArray)
  36. {
  37. this.genes = [];
  38. for(let i = 0; i < geneArray.length; i++)
  39. {
  40. this.genes.push(geneArray[i].makeClone());
  41. }
  42. }
  43. getGenes()
  44. {
  45. return this.genes;
  46. }
  47. mutate()
  48. {
  49. this.genes[Math.round(Math.random() * (this.genes.length-1))].setValue(Math.random());
  50. }
  51. createRandomChromosome()
  52. {
  53. let geneAr = [];
  54. for(let i = 0; i < this.genes.length; i++)
  55. {
  56. geneAr.push(this.genes[i].makeRandomGene());
  57. }
  58. return new Chromosome(geneAr);
  59. }
  60. }
  61. const breed = function(father, mother)
  62. {
  63. let son = new Chromosome(father.getGenes());
  64. let daughter = new Chromosome(mother.getGenes());
  65. for(let i = 0;i < son.getGenes().length; i++)
  66. {
  67. let blendCoef = Math.random();
  68. blendGene(son.getGenes()[i], daughter.getGenes()[i], blendCoef);
  69. }
  70. return [son, daughter];
  71. };
  72. function predicateBy(prop)
  73. {
  74. return function(a,b)
  75. {
  76. var result;
  77. if(a[prop] > b[prop])
  78. {
  79. result = 1;
  80. }
  81. else if(a[prop] < b[prop])
  82. {
  83. result = -1;
  84. }
  85. return result;
  86. }
  87. }
  88. const naturalSelection = function(population, keepNumber, fitnessFunction)
  89. {
  90. let fitnessArray = [];
  91. for(let i = 0; i < population.length; i++)
  92. {
  93. const fitness = fitnessFunction(population[i]);
  94. console.log(fitness);
  95. fitnessArray.push({fit:fitness, chrom: population[i]});
  96. }
  97. fitnessArray.sort(predicateBy("fit"));
  98. let survivors = [];
  99. let bestFitness = fitnessArray[0].fit;
  100. let bestChromosome = fitnessArray[0].chrom;
  101. for(let i = 0; i < keepNumber; i++)
  102. {
  103. survivors.push(fitnessArray[i].chrom);
  104. }
  105. return {survivors: survivors, bestFit: bestFitness, bestChrom: bestChromosome};
  106. };
  107. const blendGene = function(gene1, gene2, blendCoef)
  108. {
  109. let value1 = (blendCoef * gene1.getValue()) +
  110. (gene2.getValue() * (1- blendCoef));
  111. let value2 = ((1-blendCoef) * gene1.getValue()) +
  112. (gene2.getValue() * blendCoef);
  113. gene1.setValue(value1);
  114. gene2.setValue(value2);
  115. };
  116. const matePopulation = function(population, desiredPopulationSize)
  117. {
  118. let pairsNeeded = (desiredPopulationSize - population.length)/2;
  119. const originalLength = population.length;
  120. for(let i = 0; i < pairsNeeded; i++)
  121. {
  122. let index1 = Math.round(Math.random() * (originalLength-1));
  123. let index2 = Math.round(Math.random() * (originalLength-1));
  124. if(index1 !== index2)
  125. {
  126. const babies = breed(population[index1], population[index2]);
  127. population.push(babies[0]);
  128. population.push(babies[1]);
  129. }
  130. }
  131. };
  132. const mutatePopulation = function(population, mutatePercentage)
  133. {
  134. if(population.length >= 2)
  135. {
  136. let mutations = mutatePercentage *
  137. population.length *
  138. population[0].getGenes().length;
  139. for(let i = 0; i < mutations; i++)
  140. {
  141. population[i].mutate();
  142. }
  143. }
  144. else
  145. {
  146. console.log("Error, population too small to mutate");
  147. }
  148. };
  149. const newBlood = function(population, immigrationSize)
  150. {
  151. for(let i = 0; i < immigrationSize; i++)
  152. {
  153. let geneticChromosome = population[0];
  154. population.push(geneticChromosome.createRandomChromosome());
  155. }
  156. };
  157. const basicCostFunction = function(chromosome)
  158. {
  159. console.log(chromosome);
  160. console.log((chromosome.getGenes()[0].getRealValue()));
  161. return Math.abs(chromosome.getGenes()[0].getRealValue() - 6) +
  162. Math.abs(chromosome.getGenes()[1].getRealValue() - 2);
  163. };
  164. const createRandomPopulation = function(geneticChromosome, populationSize)
  165. {
  166. let population = [];
  167. for(let i = 0; i < populationSize; i++)
  168. {
  169. population.push(geneticChromosome.createRandomChromosome());
  170. }
  171. return population;
  172. };
  173. const runGeneticOptimization = function(geneticChromosome, constFunction,
  174. populationSize, maxGenerations,
  175. desiredCost, mutationRate, keepNumber,
  176. newBloodNumber)
  177. {
  178. let population = createRandomPopulation(geneticChromosome, populationSize);
  179. let generation = 0;
  180. let bestCost = Number.MAX_VALUE;
  181. let bestChromosome = geneticChromosome;
  182. do
  183. {
  184. matePopulation(population, populationSize);
  185. newBlood(population, newBloodNumber);
  186. mutatePopulation(population, mutationRate);
  187. let generationResult = naturalSelection(population, keepNumber, constFunction);
  188. if(bestCost > generationResult.bestFit)
  189. {
  190. bestChromosome = generationResult.bestChrom;
  191. bestCost = generationResult.bestFit;
  192. }
  193. population = generationResult.survivors;
  194. generation++;
  195. console.log("Generation " + generation + " Best Cost: " + bestCost);
  196. console.log(generationResult);
  197. }while(generation < maxGenerations && bestCost > desiredCost);
  198. return bestChromosome;
  199. };
  200. let gene1 = new Gene(1,10,10);
  201. let gene2 = new Gene(1,10,0.4);
  202. let geneList = [gene1, gene2];
  203. let exampleOrganism = new Chromosome(geneList);
  204. runGeneticOptimization(exampleOrganism, basicCostFunction, 100, 50, 0.01, 0.3, 20, 10);
  205. </script>
  206. </head>
  207. <body>
  208. </body>
  209. </html>