Недавно я прочитал оригинальную статью о NeuroEvolution аугментации. Топологии Кеннета О. Стэнли, и сейчас я сам пытаюсь создать прототип на JavaScript. Я наткнулся на несколько вопросов, на которые не могу ответить.
Мои вопросы:
- #P2# <блочная цитата> #P3# блочная цитата>
Есть ли причина для хранения типа узла (входной, скрытый, выходной)?
В исходной статье только соединения имеют номер инновации, но в других источниках узлы также . Это необходимо для кроссовера? (Об этом уже спрашивали здесь.)
Как я могу ограничить функции мутации, чтобы не добавлять повторяющиеся соединения?
Я думаю, что это все на данный момент. Вся помощь приветствуется.
Соответствующие части моего кода:
Геном
class Genome {
constructor(inputs, outputs) {
this.inputs = inputs;
this.outputs = outputs;
this.nodes = [];
this.connections = [];
for (let i = 0; i < inputs + outputs; i++) {
this.nodes.push(new Node());
}
for (let i = 0; i < inputs; i++) {
for (let o = 0; o < outputs; o++) {
let c = new Connection(this.nodes[i], this.nodes[inputs + o], outputs * i + o);
this.connections.push(c);
}
}
innovation = inputs * outputs;
}
weightMutatePerturb() {
let w = this.connections[Math.floor(random(this.connections.length))].weight;
w += random(-0.5, 0.5);
}
weightMutateCreate() {
this.connections[Math.floor(random(this.connections.length))].weight = random(-2, 2);
}
connectionMutate() {
let i = this.nodes[Math.floor(random(this.nodes.length))];
let o = this.nodes[Math.floor(random(this.inputs, this.nodes.length))];
let c = Connection.exists(this.connections, i, o);
if (c) {
c.enabled = true;
} else {
this.connections.push(new Connection(i, o, innovation));
innovation++;
}
}
nodeMutate() {
let oldCon = this.connections[Math.floor(Math.random(this.connections.length))];
oldCon.enabled = false;
let newNode = new Node();
this.nodes.push(newNode);
this.connections.push(new Connection(oldCon.input, newNode, innovation, 1));
innovation++;
this.connections.push(new Connection(newNode, oldCon.output, innovation, oldCon.weight));
innovation++;
}
}
Узел
class Node {
constructor() {
this.value = 0;
this.previousValue = 0;
}
}
Связь
class Connection {
constructor(input, output, innov, weight) {
this.input = input;
this.output = output;
this.innov = innov;
this.weight = weight ? weight : random(-2, 2);
this.enabled = true;
}
static exists(connections, i, o) {
for (let c = 0; c < connections.length; c++) {
if (connections[c].input === i && connections[c].output === o) {
return connections[c];
}
}
return false;
}
}
Приветствуются все ответы и источники. (Вы замечательный человек!)