私は(ほぼ)指定された文字列を見つけるための遺伝的アルゴリズムを作成できましたが、何らかの理由で半ば頻繁にエラーが発生します。単語検索遺伝アルゴリズムで時折間違い
Cannot read property 'dna' of undefined at Population.populate
私は、この問題の原因が何度か分かりません。
<!DOCTYPE html>
<html>
<head>
\t <title>Word Search</title>
\t <link href='https://fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet'>
</head>
<body style ='font-family: Ubuntu, sans-serif'>
\t Target: <input type='text' value='Hello World!' id='target'> <br>
\t Population Size: <input type='number' id='size' min='0' max='100' step='1' value='10'><br>
\t Mutation Rate: <input type='number' id='rate' min='0' max='100' step='1' value='10'>%<br>
\t <input type='submit' id='submit' onclick='evolution()'>
\t <div style='border-width: 2px; border-style: dashed; width: 250px'>
\t \t <div style='text-align: center;' id='value'>
\t \t \t <p id='generation';>Generation | 0</p>
\t \t \t <div id='pop'>
\t \t \t </div>
\t \t </div>
\t </div>
<script type="text/javascript">
window.onload = function() {
\t evolution();
}
function evolution() {
\t var population = new Population(
\t \t document.getElementById('target').value,
\t \t document.getElementById('rate').value/100,
\t \t document.getElementById('size').value);
\t var running = setInterval(function() {
\t \t document.getElementById('submit').disabled = true;
\t \t population.natSelection();
\t \t population.populate();
\t \t population.evaluate();
\t \t population.display();
\t \t if(population.completed) {
\t \t \t clearInterval(running);
\t \t \t document.getElementById('submit').disabled = false;
\t \t }
\t }, 50);
}
function Population(target, mutationRate, size) {
\t this.target = target;
\t this.mutationRate = mutationRate;
\t this.size = size;
\t this.members = [];
\t this.genePool = [];
\t this.completed = false;
\t this.generation = 0;
\t for(var i = 0; i < this.size; i++)
\t \t this.members.push(new Genome(this.target, this.mutationRate));
\t this.natSelection = function() {
\t \t for(var i = 0; i < this.members.length; i++)
\t \t \t this.members[i].calcFitness();
\t \t
\t \t this.genePool = [];
\t \t for(var i = 0; i < this.members.length; i++)
\t \t \t for(var j = 0; j < this.members[i].fitness*10; j++)
\t \t \t \t this.genePool.push(this.members[i]);
\t }
\t this.populate = function() {
\t \t this.generation++;
\t \t this.members = [];
\t \t for(var i = 0; i < this.size; i++) {
\t \t \t var a = this.genePool[Math.floor(Math.random()*this.genePool.length)].dna;
\t \t \t var b = this.genePool[Math.floor(Math.random()*this.genePool.length)].dna;
\t \t \t this.members.push(new Genome(this.target, this.mutationRate, a, b));
\t \t }
\t }
\t this.evaluate = function() {
\t \t for(var i = 0; i < this.members.length; i++) {
\t \t \t if(this.members[i].dna === this.target)
\t \t \t \t this.completed = true;
\t \t }
\t }
\t this.calcMaxFitness = function() {
\t \t var fittest = this.memebers[0].fitness;
\t \t for(var i = 1; i < this.members.length; i++)
\t \t \t if(this.memebers[i].fitness > fittest)
\t \t \t \t fittest = this.memebers[i].fitness;
\t \t return fittest;
\t }
\t this.display = function() {
\t \t document.getElementById('generation').innerHTML = 'Generation | '+this.generation;
\t \t var div = document.getElementById('pop');
\t \t div.innerHTML = '';
\t \t for(var i = 0; i < this.members.length; i++) {
\t \t \t div.innerHTML += this.members[i].dna+'<br>'
\t \t }
\t }
}
function Genome(target, mutationRate, parentA, parentB) {
\t this.dna = '';
\t this.fitness = 0;
\t this.target = target;
\t this.mutationRate = mutationRate;
\t this.mutate = function() {
\t \t for(var i = 0; i < this.target.length; i++) {
\t \t \t if(this.dna.charCodeAt(i) != this.target.charCodeAt(i))
\t \t \t \t if(Math.random() > this.mutationRate)
\t \t \t \t \t this.dna = this.dna.replaceAt(i, String.fromCharCode(Math.floor(Math.random()*94+32)));
\t \t }
\t }
\t if(!parentA && !parentB) {
\t \t for(var i = 0; i < this.target.length; i++)
\t \t \t this.dna += String.fromCharCode(Math.floor(Math.random()*94+32));
\t } else {
\t \t var mid = Math.floor(Math.random()*this.target.length);
\t \t this.dna = parentA.substr(0, mid) + parentB.substr(mid, parentB.length);
\t \t this.mutate();
\t }
\t
\t this.calcFitness = function() {
\t \t this.fitness = 0;
\t \t for(var i = 0; i < this.target.length; i++) {
\t \t \t if(this.dna.charCodeAt(i) === this.target.charCodeAt(i))
\t \t \t \t this.fitness++;
\t \t }
\t }
}
Number.prototype.map = function (in_min, in_max, out_min, out_max) {
return (this - in_min) * (out_max - out_min)/(in_max - in_min) + out_min;
}
String.prototype.replaceAt=function(index, replacement) {
return this.substr(0, index) + replacement+ this.substr(index + replacement.length);
}
</script>
</body>
</html>
もちろん!今はとても分かりました。私はそれについても考えていませんでした。助けてくれてありがとう。 私が実装したソリューションは、各ゲノムの適合度を0からthis.target.length、this.target.lengthの0.1にマッピングします。 –