vrp-tabu-search
Version:
Tabu Search Algorithm for Vehicle Routing Problem
119 lines (96 loc) • 3.15 kB
JavaScript
/**
* Created by tnlam on 5/7/15.
*/
var util = require('util');
var assert = require('assert');
var defineClass = require('simple-cls').defineClass;
var Class = require('simple-cls').Class;
var Matrix = require('sylvester').Matrix;
var Vector = require('sylvester').Vector;
var xml2js = require('xml2js');
var fisher_yates_permute = require('../../util/permute.js');
var OProblem = require('../../core/OProblem.js');
var VRPSolution = require('./Solution.js');
var VRP = defineClass({
name: 'VRP',
extend: OProblem,
construct: function (nodes, data, capacity, solution) {
if (data instanceof Array) {
data = $M(data);
}
if (nodes instanceof Array) {
nodes = $V(nodes);
}
OProblem.call(this, nodes, data, capacity, solution, true);
},
methods: {
valid: function (candidate) {
//assert(Class.isInstanceOfClass(candidate, 'VRPSolution'));
//
//var val = {}; // index from node index to occurance count
//for (var i = 1; i <= candidate.data.elements.length; i++) {
// var idx = candidate.data.e(i);
// if (!val[idx]) val[idx] = 1;
// else val[idx] += 1;
//}
//// once and only once
//var nodeCount = this.data.elements.length;
//for (var i = 1; i <= nodeCount; i++)
// if (val[i] != 1) return false;
return true;
},
fitness: function (candidate) {
var total_dist = 0.0;
for (var i = 0; i < candidate.data.elements.length; i++) {
for (var j = 0; j < candidate.data.elements[i].length-1; j++) {
var pre = candidate.data.e(i+1)[j];
var cur = candidate.data.e(i+1)[j+1];
//console.log('pre: ' + pre + ', cur: ' + cur);
//console.log('this.data.e(pre+1,cur+1) = ' + this.data.e(pre+1,cur+1));
//console.log('data = ' + this.data.e(pre+1, cur+1));
total_dist = total_dist + this.data.e(pre+1, cur+1);
//console.log('total_dist = ' + total_dist);
}
}
return total_dist;
},
demand: function (route) {
var value = 0;
//console.log(route);
for (var i = 1; i < route.length-1; i++) {
//console.log(this.nodes.e(i+1));
//console.log('route[' + route[i] + '] = ' + this.nodes.e(route[i]+1).amount);
value += this.nodes.e(route[i]+1).amount;
}
//console.log(value);
return value;
},
randsol: function () {
//produce a random solution
var sol = [];
for (var i = 1; i <= this.dimension(); i++) sol.push(i);
fisher_yates_permute(sol);
var ret = new VRPSolution($V(sol));
ret.fitness = this.fitness(ret);
return ret;
},
initSolution: function (sol) {
var ret = new VRPSolution($V($V(sol)));
ret.fitness = this.fitness(ret);
return ret;
},
dimension: function () {
//console.log('dimension from Problem.js');
return this.solution.length; // an array
}
},
statics : {
parseData: function (raw) {
return $M(data);
},
validData: function (data) {
return true;
}
}
});
module.exports = exports = VRP;