Ich versuche eine genetische Algorithmus-Simulation in JavaScript mithilfe der P5.JS-Bibliothek durchzuführen, aber ich habe einige Probleme. Hier ist, was ich bisher:JS - Fehler: "Eigenschaft von undefiniert nicht lesen"
//var popS = 2;
var popu;
//var balls = [];
var target;
function setup() {
createCanvas(800, 300);
popu = new Population();
target = createVector(width - 15, height/2);
}
function draw() {
background(50);
popu.run();
var ballsC = 0;
for (var a = 0; a < popu.balls.length; a++) {
if (popu.balls[a].done == true){
ballsC++;
}
}
if (ballsC >= popu.popS) {
//popu = new Population();
popu.evaluate();
//popu.selection();
}
fill(255, 0, 30);
noStroke();
ellipse(target.x, target.y, 20, 20);
}
function DNA() {
this.genes = [];
this.changes = 7;//random(2, 50);
for (var a = 0; a < this.changes; a++) {
this.genes[a] = random(0, 15);
}
this.crossover = function (pB) {
var newdna = new DNA();
var mid = floor(random(0, this.genes.length));
for (var a = 0; a < this.genes.length; a++) {
if (a < mid) {
newdna.genes[a] = this.genes[a];
}else {
newdna.genes[a] = pB.genes[a];
}
}
return newdna;
}
}
function Population() {
this.balls = [];
this.popS = 50;
this.maxfit = 0;
this.matingpool = [];
for (var a = 0; a < this.popS; a++) {
this.balls[a] = new Ball();
}
this.evaluate = function() {
for (var a = 0; a < this.balls.length; a++) {
this.balls[a].calcF();
if (this.balls[a].fitness > this.maxfit) {
this.maxfit = this.balls[a].fitness;
}
}
this.matingpool = [];
for (var b = 0; b < this.balls.length; b++) {
var n = this.balls[b].fitness * 100;
for (var c = 0; c < n; c++) {
this.matingpool.push(this.balls[c]);
}
}
this.selection();
}
this.selection = function() {
var newBalls = [];
for (var a = 0; a < this.balls.length; a++) {
var parentA = this.matingpool[floor(random(0, this.matingpool.length))];
var parentB = this.matingpool[floor(random(0, this.matingpool.length))];
var child = parentA.dna.crossover(parentB.dna);
newBalls[a] = new Ball(child);
}
this.balls = newBalls;
}
this.run = function() {
for (var a = 0; a < this.balls.length; a++) {
this.balls[a].update();
this.balls[a].checkCol();
this.balls[a].show();
}
}
}
function Ball(dna) {
this.pos = createVector(10, height/2);
this.speed = createVector(2, 2.5);
this.mul = -1;
this.time = 0;
this.a = 0;
if (dna) {
this.dna = dna;
} else {
this.dna = new DNA();
}
this.done = false;
this.fitness = 0;
this.reached;
this.update = function() {
if (this.done == false) {
if (this.time >= this.dna.genes[this.a]) {
this.a++;
this.time = 0;
this.mul *= -1;
}
this.speed.set(2, 2.5 * this.mul);
this.pos.add(this.speed);
}
}
this.show = function() {
this.time += 0.1;
fill(255, 70);
noStroke();
ellipse(this.pos.x, this.pos.y, 10, 10);
}
this.checkCol = function() {
if (this.pos.y > height || this.pos.y < 0 || this.pos.x > width) {
//print("col");
this.done = true;
}
if (dist(this.pos.x, this.pos.y, target.x, target.y) <= (10/2) + (20/2)) {
//print("done!");
this.done = true;
this.reached = true;
}
}
this.calcF = function() {
var a = dist(this.pos.x, this.pos.y, target.x, target.y);
var b = this.dna.genes.length;
var c = 0;
if (this.reached){
c = 1;
}
this.fitness = map(map(a, 0, width, 1, 0) + map(b, 2, 50, 1, 0) + c, 0, 3, 0, 1);
}
}
Dies ist der wichtigste Teil des Codes:
var popu;
function setup() {
createCanvas(800, 300);
popu = new Population();
}
function draw() {
background(50);
//popu = new Population();
popu.evaluate();
//popu.selection();
}
function DNA() {
this.genes = [];
this.changes = 7; //random(2, 50);
for (var a = 0; a < this.changes; a++) {
this.genes[a] = random(0, 15);
}
this.crossover = function(pB) {
var newdna = new DNA();
var mid = floor(random(0, this.genes.length));
for (var a = 0; a < this.genes.length; a++) {
if (a < mid) {
newdna.genes[a] = this.genes[a];
} else {
newdna.genes[a] = pB.genes[a];
}
}
return newdna;
}
}
function Population() {
this.balls = [];
this.popS = 50;
this.maxfit = 0;
this.matingpool = [];
for (var a = 0; a < this.popS; a++) {
this.balls[a] = new Ball();
}
this.evaluate = function() {
this.matingpool = [];
for (var b = 0; b < this.balls.length; b++) {
var n = this.balls[b].fitness * 100;
for (var c = 0; c < n; c++) {
this.matingpool.push(this.balls[c]);
}
}
this.selection();
}
this.selection = function() {
var newBalls = [];
for (var a = 0; a < this.balls.length; a++) {
var parentA = this.matingpool[floor(random(0, this.matingpool.length))];
var parentB = this.matingpool[floor(random(0, this.matingpool.length))];
var child = parentA.dna.crossover(parentB.dna);
newBalls[a] = new Ball(child);
}
this.balls = newBalls;
}
}
function Ball(dna) {
this.pos = createVector(10, height/2);
this.speed = createVector(2, 2.5);
this.mul = -1;
this.time = 0;
this.a = 0;
if (dna) {
this.dna = dna;
} else {
this.dna = new DNA();
}
this.done = false;
this.fitness = 0;
this.reached;
}
Also, wenn es hier bekommt:
this.selection = function() {
var newBalls = [];
for (var a = 0; a < this.balls.length; a++) {
var parentA = random(this.matingpool);
var parentB = random(this.matingpool);
var child = parentA.dna.crossover(parentB.dna);
newBalls[a] = new Ball(child);
}
this.balls = newBalls;
}
i das bekommen Fehler: "Kann Eigenschaft 'DNA' von undefined nicht lesen, warum in aller Welt passiert das?" Wenn ich den Debugger in Chrome verwende, kann ich klar sehen, dass der Paarungspool 2000 Elemente hat, aber wenn ich versuche, einen zufälligen zu bekommen, gibt es "undefined" zurück.
Die komische Sache ist, dass elterB funktioniert, aber parentA tut nicht.
Jede Hilfe ist sehr geschätzt. Entire Code läuft hier: http://codepen.io/felipe_mare/pen/bgOYMN
Wenn es hilft, ich manchmal den Fehler: „Kann nicht lesen Eigenschaft‚0‘undefinierten“ statt, an der Linie 138
this.update = function() {
if (this.done == false) {
//line 138
if (this.time >= this.dna.genes[this.a]) {
//line 138
this.a++;
this.time = 0;
this.mul *= -1;
}
this.speed.set(2, 2.5 * this.mul);
this.pos.add(this.speed);
}
}
Wie sieht dein 'random()' aus? – JohanP
@JohanP Bitte beachten Sie das Tag [tag: p5.js]. Die P5.js-Bibliothek bietet die Funktion 'random()'. –
Welche Zeile ist "Zeile 138"? – Li357