我在处理一些机器学习方面的问题时遇到了困难。第一代火箭变异后,它们并未改变路径,而是继续沿着相同的轨迹前进。我尝试了多种方法来解决这个问题,如你所见,但这些方法都不奏效。我在openprocessing.org上编写了这段代码,也尝试在本地运行过。我没发现问题所在,但我想问题可能出在Rocket构造函数中。
var rockets = [];var bf = -1;var br;function setup() { createCanvas(windowWidth, windowHeight); background(100); noStroke(); fill(255, 50); frameRate(10); target = createVector(width, height / 2); for (var i = 0; i < 10; i++) { rockets.push(new Rocket()); }}function draw() { background(100); ellipse(width / 2, height / 2, 40, 40); ellipse(width - 10, height / 2, 40, 40); for (i = 0; i < rockets.length; i++) { rockets[i].show(); //console.log(rockets[i].pos.y); if (!rockets[i].killed) { rockets[i].applyForce(); //it is a fittness counter inside } } //console.log(rockets); if (rockets[0].counter >= rockets[0].route.length) { findBest(); respawn(); }}function respawn() { var news = mutate(br); for (var i = 0; i < 10; i++) { rockets.push(new Rocket()); //console.log(rockets); rockets[i].route = news[i]; }}function findBest() { for (var i = 0; i < rockets.length; i++) { //console.log(rockets[i].fittness); if (rockets[i].fittness > bf) { br = rockets[i].route; bf = rockets[i].fittness; } } rockets = [];}function mutate(arr) { var news = []; for (var i = 0; i < 10; i++) { var tempArr = arr; tempArr[floor(random(arr.lenth))] = p5.Vector.random2D().setMag(30); news.push(tempArr); } return news;}function Rocket(a) { this.pos = createVector(width / 2, height / 2); this.route = []; this.counter = 0; this.fittness = 0; this.killed = false; //console.log(a); if (!a) { for (var i = 0; i < 20; i++) { this.route.push(p5.Vector.random2D()); this.route[i].setMag(20); //console.log("!A"); // console.log(i); } } else { // this is not used this.route = a; // for(var i = floor(random(a.length-1)); i<a.length; i++) { //console.log(this.route[i]); b = floor(random(this.route.length - 1)); console.log("before: ", this.route[b]); this.route[b] = p5.Vector.random2D().setMag(30); //this.route[i].rotate(0.2*pow(-1, i)); console.log("after: ", this.route[b]); //} } //console.log(mutate(this.route)); this.applyForce = function() { if (this.counter == this.route.length - 1) { this.countFittness(); //console.log(this.fittness); this.killed = true; } this.pos.add(this.route[this.counter]); this.counter++; } this.countFittness = function() { this.fittness = 1 / this.pos.dist(target) * 100; //console.log(this.fittness); } this.show = function() { ellipse(this.pos.x, this.pos.y, 10, 10); }}
<html><head> <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.12/p5.js"></script></head></html>
回答:
不错的代码。看起来你的mutate函数中有一个错误:
function mutate(arr) { var news = []; for (var i = 0; i < 10; i++) { var tempArr = arr; tempArr[floor(random(arr.length))] = p5.Vector.random2D().setMag(30); news.push(tempArr); } return news;}
当你使用
var tempArr = arr;
在JavaScript中,你并没有得到数组的副本。两个数组都指向同一个引用。当你改变其中一个时,原始数组也会随之改变。这样,最终所有的火箭路径都会变成相同的结果。
尝试使用…
var tempArr = arr.slice();
slice()操作会克隆数组并返回新数组的引用。
在同一个函数中还存在一个小小的拼写错误。我认为应该是…
tempArr[floor(random(arr.length))] = p5.Vector.random2D().setMag(30);