Commit
- Loading branch information
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# Auto detect text files and perform LF normalization | ||
* text=auto |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
//a connection between 2 nodes | ||
class connectionGene { | ||
constructor(from, to, w, inno) { | ||
this.fromNode = from; | ||
this.toNode = to; | ||
this.weight = w; | ||
this.enabled = true; | ||
this.innovationNo = inno; //each connection is given a innovation number to compare genomes | ||
|
||
} | ||
|
||
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ||
//changes the this.weight | ||
mutateWeight() { | ||
var rand2 = random(1); | ||
if (rand2 < 0.1) { //10% of the time completely change the this.weight | ||
this.weight = random(-1, 1); | ||
} else { //otherwise slightly change it | ||
this.weight += (randomGaussian() / 50); | ||
//keep this.weight between bounds | ||
if (this.weight > 1) { | ||
this.weight = 1; | ||
} | ||
if (this.weight < -1) { | ||
this.weight = -1; | ||
|
||
} | ||
} | ||
} | ||
|
||
//---------------------------------------------------------------------------------------------------------- | ||
//returns a copy of this connectionGene | ||
clone(from, to) { | ||
var clone = new connectionGene(from, to, this.weight, this.innovationNo); | ||
clone.enabled = this.enabled; | ||
|
||
return clone; | ||
} | ||
|
||
|
||
//------------------------------------------------------------------------------------------------------------------- | ||
//returns whether or not these 2 connection genes are the same | ||
isEqualTo(otherConnectionGene) { | ||
return this.fromNode.number === otherConnectionGene.fromNode.number && this.toNode.number === otherConnectionGene.toNode.number | ||
&& this.weight === otherConnectionGene.weight && this.enabled === otherConnectionGene.enabled && this.innovationNo === otherConnectionGene.innovationNo; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
class connectionHistory { | ||
constructor(from, to, inno, innovationNos) { | ||
this.fromNode = from; | ||
this.toNode = to; | ||
this.innovationNumber = inno; | ||
this.innovationNumbers = []; //the innovation Numbers from the connections of the genome which first had this mutation | ||
//this represents the genome and allows us to test if another genoeme is the same | ||
//this is before this connection was added | ||
arrayCopy(innovationNos, this.innovationNumbers); //copy (from, to) | ||
} | ||
|
||
//---------------------------------------------------------------------------------------------------------------- | ||
//returns whether the genome matches the original genome and the connection is between the same nodes | ||
matches(genome, from, to) { | ||
if (genome.genes.length === this.innovationNumbers.length) { //if the number of connections are different then the genoemes aren't the same | ||
if (from.number === this.fromNode && to.number === this.toNode) { | ||
//next check if all the innovation numbers match from the genome | ||
for (var i = 0; i < genome.genes.length; i++) { | ||
if (!this.innovationNumbers.includes(genome.genes[i].innovationNo)) { | ||
return false; | ||
} | ||
} | ||
//if reached this far then the innovationNumbers match the genes innovation numbers and the connection is between the same nodes | ||
//so it does match | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
class Node { | ||
|
||
constructor(no) { | ||
this.number = no; | ||
this.inputSum = 0; //current sum i.e. before activation | ||
this.outputValue = 0; //after activation function is applied | ||
this.outputConnections = []; //new ArrayList<connectionGene>(); | ||
this.layer = 0; | ||
this.drawPos = createVector(); | ||
} | ||
|
||
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ||
//the node sends its output to the inputs of the nodes its connected to | ||
engage() { | ||
if(this.layer != 0) { //no sigmoid for the inputs and bias | ||
this.outputValue = this.sigmoid(this.inputSum); | ||
} | ||
|
||
for(var i = 0; i < this.outputConnections.length; i++) { //for each connection | ||
if(this.outputConnections[i].enabled) { //dont do shit if not enabled | ||
this.outputConnections[i].toNode.inputSum += this.outputConnections[i].weight * this.outputValue; //add the weighted output to the sum of the inputs of whatever node this node is connected to | ||
} | ||
} | ||
} | ||
//---------------------------------------------------------------------------------------------------------------------------------------- | ||
//not used | ||
stepFunction(x) { | ||
if(x < 0) { | ||
return 0; | ||
} else { | ||
return 1; | ||
} | ||
} | ||
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ||
//sigmoid activation function | ||
sigmoid(x) { | ||
return 1.0 / (1.0 + pow(Math.E, -4.9 * x)); //todo check pow | ||
} | ||
//---------------------------------------------------------------------------------------------------------------------------------------------------------- | ||
//returns whether this node connected to the parameter node | ||
//used when adding a new connection | ||
isConnectedTo(node) { | ||
if(node.layer == this.layer) { //nodes in the same this.layer cannot be connected | ||
return false; | ||
} | ||
|
||
//you get it | ||
if(node.layer < this.layer) { | ||
for(var i = 0; i < node.outputConnections.length; i++) { | ||
if(node.outputConnections[i].toNode == this) { | ||
return true; | ||
} | ||
} | ||
} else { | ||
for(var i = 0; i < this.outputConnections.length; i++) { | ||
if(this.outputConnections[i].toNode == node) { | ||
return true; | ||
} | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ||
//returns a copy of this node | ||
clone() { | ||
var clone = new Node(this.number); | ||
clone.layer = this.layer; | ||
return clone; | ||
} | ||
} |