Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
danielkv authored Apr 8, 2019
1 parent 1245903 commit f8a1779
Show file tree
Hide file tree
Showing 8 changed files with 936 additions and 0 deletions.
182 changes: 182 additions & 0 deletions ai/class.ai.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
class AI {
constructor (NeuralNetwork, populationSize, mutation, variationMutation, maxGenerations) {
this.maxGenerations = maxGenerations;
this.NeuralNetwork = NeuralNetwork;
this.populationSize = populationSize;
this.population = Array();
this.mutation = mutation;
this.variationMutation = variationMutation;
this.generation = 0;
this.actualSubject = 0;
this.learning = false;
this.numberOfChromosomes = 2;
this.parentSurvive = true;

this.init();
}

startLearning() {
this.learning = true;
}

stopLearning() {
this.learning = false;
}

init() {
this.resetGeneration();
this.createNewPopulation();
}

setInput (input) {
this.NeuralNetwork.setInput(input);
}

calculate () {
return this.NeuralNetwork.calculate();
}

resetGeneration () {
this.actualSubject = 0;
this.generation++;
}

createNewPopulation (startPopulation) {
if (!startPopulation)
var newPopulation = Array();
else
var newPopulation = startPopulation;

for (let i=newPopulation.length; i<this.populationSize; i++) {
newPopulation.push(new Chromosome(this.NeuralNetwork.inputSize, this.NeuralNetwork.hiddenSize));
}
this.population = newPopulation;

this.NeuralNetwork.setHiddenLayer(this.population[this.actualSubject]);

document.dispatchEvent(new CustomEvent('onNewPopulation', {detail : {population:this.population}}));
}

evolve () {
if (this.learning && this.generation < this.maxGenerations) {
var bestGens = this.selectBestPopulation();
var newGeneration = Array();
var crossover = this.copyChromosome(this.doCrossover(bestGens));
if (this.parentSurvive) {
this.resetFitness(bestGens);
newGeneration = bestGens;
}
newGeneration = newGeneration.concat(crossover);

this.resetGeneration();

this.createNewPopulation(this.mutate(newGeneration));
}
}

nextSubject () {
if (this.generation >= this.maxGenerations) this.stopLearning();
if (!this.learning) return;

if (this.actualSubject == this.population.length-1) {
this.evolve();
} else {
this.actualSubject++;
this.NeuralNetwork.setHiddenLayer(this.population[this.actualSubject]);
}
}

mutate (chromosomes) {
for (let i=0; i<chromosomes.length; i++) {
chromosomes[i].mutate(this.mutation, this.variationMutation);
}
return chromosomes;
}

addFitness () {
if (!this.learning) return;

this.NeuralNetwork.addFitness();
}

resetFitness (chromosomes) {
for (let i=0; i<chromosomes.length; i++) {
chromosomes[i].resetFitness();
}
}

doCrossover (chromosomes) {

if (chromosomes.length > 2) {
console.log("Número máximo de Chromosomes para Crossover é 2");
return false;
}
var sliceSize1 = Math.floor(Math.random()*(this.NeuralNetwork.hiddenSize - 1 + 1) + 1);
var sliceSize2 = sliceSize1 - this.NeuralNetwork.hiddenSize;

var n1 = chromosomes[0].neurons;
var n2 = chromosomes[1].neurons;

var slice1 = n1.slice(0, sliceSize1-1);
var slice2 = n1.slice(sliceSize1-1);
var slice3 = n2.slice(0, sliceSize2-1);
var slice4 = n2.slice(sliceSize2-1);

var c1 = slice1.concat(slice4);
var c2 = slice3.concat(slice2);

var chromosome1 = new Chromosome(this.NeuralNetwork.inputSize, this.NeuralNetwork.hiddenSize);
var chromosome2 = new Chromosome(this.NeuralNetwork.inputSize, this.NeuralNetwork.hiddenSize);

chromosome1.setNeurons(c1);
chromosome2.setNeurons(c2);

return [chromosome1, chromosome2];
}

copyChromosome(chromosomes) {
if (!Array.isArray(chromosomes)) chromosomes = [chromosomes];

var newChromosomes = Array();
for (let i=0; i<chromosomes.length; i++) {

var copied = Object.assign(
Object.create(
Object.getPrototypeOf(chromosomes[i])
),
chromosomes[i]
);

copied.setNeurons(chromosomes[i].neurons);

for (let k=0; k<copied.neurons.length; k++) {
copied.neurons[k].clone = true;
}

newChromosomes.push(copied);
}

return newChromosomes;
}

sortChromosomes (a, b) {
if (a.getFitness() > b.getFitness()) {
return -1;
} else if (a.getFitness() < b.getFitness()) {
return 1;
}

return -1;
}



selectBestPopulation () {
var actualGroup = this.population;
actualGroup.sort(this.sortChromosomes);

return actualGroup.slice(0,this.numberOfChromosomes);
}

//aAQUIUIIIIIIIIIIIII
}
114 changes: 114 additions & 0 deletions ai/class.chromosome.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
class Chromosome {
constructor (inputSize, size) {
this.size = size;
this.inputSize = inputSize;
this.input = '';
this.fitness = 0;
this.bias = 0;
this.neurons = this.createNeurons();
}

setBias (bias) {
for (let i=0; i<this.size; i++) {
this.neurons[i].setBias(bias);
}
this.bias = bias;
}

setNeurons (neurons) {
if (!Array.isArray(neurons)) {
console.error("Esse não é um Array de Neurons");
return false;
}
if (neurons.length != this.size) {
console.error("Tamanho dos Neurons diferente (Chomosome)");
return false;
}

var n = Array();
for (let i=0; i<neurons.length; i++) {
let nCopy = Object.assign(
Object.create(
Object.getPrototypeOf(neurons[i])
),
neurons[i]
);
n.push(nCopy);
}

this.neurons = n;

this.resetFitness();
}

createNeurons () {
var neurons = Array();
for (let i=0; i<this.size; i++) {
neurons.push(new Neuron(this.inputSize, this.bias));
}
return neurons;
}

setInput (input) {
if (!Array.isArray(input)) input = [input];
if (input.length != this.inputSize) {
console.error('Tamanho do input diferente (Chromosome)');
return false;
}

this.input = input;

for (let i=0; i<this.neurons.length; i++) {
this.neurons[i].setInput(input);
}
}

calculate() {
if (this.bias == 0) console.error("Bias não está definido (Chromosome)");
if (this.input.length === 0) {
console.error('Input vazio (Chromosome)');
return false;
}
var results = Array();
for (let i=0; i<this.neurons.length; i++) {
results.push(this.neurons[i].calculate());
}
return results;
}

mutate (mutation, variation) {
var pctUnique = 100 / this.neurons.length;
var mutant = 0;
var i = 0;
while (mutant < mutation) {
if (Math.random() > .7) {
this.neurons[i].mutate(mutation, variation);
mutant += pctUnique;
}
i++;
if (i >= this.neurons.length) i = 0;
}
}

setFitness (fitness) {
this.fitness = fitness;
}

addFitness() {
this.fitness++;
}

getFitness () {
return this.fitness;
}

resetFitness () {
this.fitness = 0;
}

print() {
for (let i=0; i<this.neurons.length; i++) {
this.neurons[i].print();
}
}
}
78 changes: 78 additions & 0 deletions ai/class.neuralNetwork.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
class NeuralNetwork {
constructor (inputSize, hiddenSize, outputSize, bias) {
this.bias = bias;
this.input = '';
this.inputSize = inputSize;
this.outputSize = outputSize;
this.hiddenSize = hiddenSize;

this.createOutputLayer();
}

setInput (input) {
if (!Array.isArray(input)) input = [input];
if (input.length == this.inputSize)
this.input = input;
else
console.error("Entrada tem tamanho diferente. (Neural Network)");

this.hiddenLayer.setInput(input);
}

calculate() {
if (this.input.length === 0) {
console.error('Input vazio (Neural Network)');
return false;
}
var resultHidden = this.hiddenLayer.calculate();

this.outputLayer.setInput(resultHidden);

var resultOutput = this.outputLayer.calculate();
if (!resultOutput) {
console.error("Erro ao calcular camada de saída", resultOutput);
//return false;
}

//return resultOutput;
return this.serializeResult(resultOutput);
}

serializeResult(result) {
var r = Array();
for (let i=0; i<result.length; i++) {
r.push(this.sigmoid(result[i]));
}
return r;
}

sigmoid (x) {
return 1/(1+Math.pow(Math.E, -x));
}

setHiddenLayer (hiddenLayer) {
if (hiddenLayer instanceof Chromosome) {
this.hiddenLayer = hiddenLayer;
this.hiddenLayer.setBias(this.bias);
} else
console.error("Hidden Layer não é do tipo 'Chromosome'.");
}

createOutputLayer () {
var outputLayer = new Chromosome(this.hiddenSize, this.outputSize);
this.outputLayer = outputLayer;
this.outputLayer.setBias(this.bias);
return outputLayer;
}

addFitness () {
this.hiddenLayer.addFitness();
}

print() {
console.table(this.input);
this.hiddenLayer.print();
//console.table();
//console.table(this.outputLayer);
}
}
Loading

0 comments on commit f8a1779

Please sign in to comment.