dolphin278 / genetic

Implementation of genetic algorithms for nodejs
179 stars 41 forks source link

Cannot read property 'score' of undefined #10

Open maluramichael opened 7 years ago

maluramichael commented 7 years ago

Someone got this problem before? I cannot run more than 100 generations.

/Users/michaelmalura/Development/bot/node_modules/genetic/lib/genetic/Task.js:210
            level += self.parents[position].score
                                           ^

TypeError: Cannot read property 'score' of undefined
    at /Users/michaelmalura/Development/bot/node_modules/genetic/lib/genetic/Task.js:210:44
    at Object.async.until (/Users/michaelmalura/Development/bot/node_modules/genetic/node_modules/async/lib/async.js:568:13)
    at /Users/michaelmalura/Development/bot/node_modules/genetic/lib/genetic/Task.js:198:13
    at /Users/michaelmalura/Development/bot/node_modules/genetic/node_modules/async/lib/async.js:486:21
    at /Users/michaelmalura/Development/bot/node_modules/genetic/node_modules/async/lib/async.js:185:13
    at iterate (/Users/michaelmalura/Development/bot/node_modules/genetic/node_modules/async/lib/async.js:108:13)
    at /Users/michaelmalura/Development/bot/node_modules/genetic/node_modules/async/lib/async.js:119:25
    at /Users/michaelmalura/Development/bot/node_modules/genetic/node_modules/async/lib/async.js:187:17
    at /Users/michaelmalura/Development/bot/node_modules/genetic/node_modules/async/lib/async.js:491:34
    at /Users/michaelmalura/Development/bot/node_modules/genetic/lib/genetic/Task.js:192:7
function random(start, end) {
    return Math.floor(Math.random() * end) + start;
};

function getRandomSolution(callback) {
    // let threshhold = 0.03;
    // let buyCut = 3;
    // let sellCut = 8;

    callback({
        threshhold: random(0.02, 0.3), // 2% - 30%
        buyCut: random(1, 100), // 1/1 - 1/100
        sellCut: random(1, 100) // 1/1 - 1/100
    })
}

function fitness(solution, callback) {
    const { profit, sells, buys } = simulate(stockData, Object.assign({}, solution));
    callback(profit)
}

function mutate(solution, callback) {
    let s = Object.assign({}, solution);
    if (Math.random() < 0.3) {
        s.threshhold = random(0.02, 0.3);
    }
    if (Math.random() < 0.3) {
        s.buyCut = random(1, 100);
    }
    if (Math.random() < 0.3) {
        s.sellCut = random(1, 100);
    }
    callback(s)
}

function crossover(father, mother, callback) {
    var child = {};

    assert(!!father, `No father`);
    assert(!!mother, `No mother`);

    if (Math.random() >= 0.5) {
        child.threshhold = father.threshhold;
    } else {
        child.threshhold = mother.threshhold;
    }

    if (Math.random() >= 0.5) {
        child.sellCut = father.sellCut;
    } else {
        child.sellCut = mother.sellCut;
    }

    if (Math.random() >= 0.5) {
        child.buyCut = father.buyCut;
    } else {
        child.buyCut = mother.buyCut;
    }
    callback(child);
}

function stopCriteria() {
    return (this.generation === 300)
}

const geneticOptions = {
    getRandomSolution: getRandomSolution,  // previously described to produce random solution
    popSize: 100,  // population size
    stopCriteria: stopCriteria,  // previously described to act as stopping criteria for entire process
    fitness: fitness,  // previously described to measure how good your solution is
    minimize: false,  // whether you want to minimize fitness function. default is `false`, so you can omit it
    mutateProbability: 0.1,  // mutation chance per single child generation
    mutate: mutate,  // previously described to implement mutation
    crossoverProbability: 0.3, // crossover chance per single child generation
    crossover: crossover // previously described to produce child solution by combining two parents
}

const runEvolution = function () {
    const taskInstance = new Task(geneticOptions);
    taskInstance.on('error', function (error) { console.log('ERROR - ', error) })
    taskInstance.run(function (stats) {
        console.log('results', stats);
    });
}
eugenioclrc commented 6 years ago

same here!

const Task = require('genetic').Task;

const options = {
  getRandomSolution : getRandomSolution,
  popSize : 500,
  stopCriteria : stopCriteria,
  fitness : fitness,
  minimize : true,
  mutateProbability : 0.1,
  mutate : mutate,
  crossoverProbability : 0.3,
  crossover : crossover
}
const util = require('util');

function crossover(parent1, parent2, callback) {
  var child = {}
  if (Math.random()>0.5) {
    child.a = parent1.a
  }
  else {
    child.a = parent2.a
  }
  if (Math.random()>0.5) {
    child.b = parent1.b
  }
  else {
    child.b = parent2.b
  }
  if (Math.random()>0.5) {
    child.c = parent1.c
  }
  else {
    child.c = parent2.c
  }
  callback(child)
}

function mutate(solution, callback) {
  if (Math.random()<0.3) {
    solution.a = Math.random()
  }
  if (Math.random()<0.3) {
    solution.b = Math.random()
  }
  if (Math.random()<0.3) {
    solution.c = Math.random()
  }
  callback(solution)
}

function getRandomSolution(callback) {
  var solution = { a: Math.random(), b: Math.random(), c: Math.random() };

  callback(solution)
}

function stopCriteria() {
  return (this.generation == 1000)
}

function fitness(solution, callback) {
  callback(Math.abs(Math.pow(solution.a,2)+solution.b+solution.c - 10))
}

console.log('=== TEST BEGINS === ')
var
  t = new Task(options)
t.on('error', function (error) { console.log('ERROR - ', error) })
t.run(function (stats) {
  console.log('results', stats);
})
palmerabollo commented 6 years ago

Same here. Did you find a solution/workaround?

jimmyleray commented 6 years ago

I think there is a problem with the negative scores, and / or when we set "minimize" to true, which is like having negative scores.

nemozny commented 6 years ago

same here, I am having the error 2/3 runs, some configurations of crossover won't run at all