vrp-tabu-search
Version:
Tabu Search Algorithm for Vehicle Routing Problem
117 lines (100 loc) • 3.63 kB
JavaScript
/**
* Created by tnlam on 5/7/15.
*/
var util = require('util');
var assert = require('assert');
var defineClass = require('simple-cls').defineClass;
var Matrix = require('sylvester').Matrix;
var Vector = require('sylvester').Vector;
var VRPSolution = require('./Solution.js');
var TS = require('../../core/TS.js');
function neighbors (candidate) {
//console.log('candidate ne');
//console.log(candidate);
assert(this.problem.valid(candidate));
var self = this;
var neighbors = [];
//console.log(this.problem);
var N = this.problem.dimension(); // number of city nodes
//console.log('N = ' + N);
var E = N; // number of travel paths
// enumerate all possible pair of edges to remove
//var origin = candidate.data.elements.slice(0);
//console.log(origin);
for (var i = 0; i < N-1; i++) {
for (var j = 1; j < N; j++) {
var ar = [];
for (var k = 0; k < candidate.data.elements.length; k++) {
ar.push(candidate.data.elements[k].slice());
}
//console.log('-ar');
//console.log(ar);
var r1 = ar[i];
var r2 = ar[j];
//console.log('original r1: ' + r1);
//console.log('original r2: ' + r2);
for (var x = 1; x < r1.length-1; x++) {
for (var y = 1; y < r2.length-1; y++) {
//console.log('x = ' + x + ', y = ' + y);
var tmp = r1[x];
r1[x] = r2[y];
r2[y] = tmp;
//console.log('so sanh');
//console.log(self.problem.demand(r1) <= self.problem.capacity);
//console.log(self.problem.demand(r2) <= self.problem.capacity);
if (self.problem.demand(r1) <= self.problem.capacity &&
self.problem.demand(r2) <= self.problem.capacity) {
//console.log('r1: ' + r1 + ', demands = ' + self.problem.demand(r1));
//console.log('r2: ' + r2 + ', demands = ' + self.problem.demand(r2));
ar[i] = r1.slice();
ar[j] = r2.slice();
//console.log(ar);
//console.log(new VRPSolution($V($V(ar))));
//if (i == 0 && j == 1 && x == 1 && y == 1) {
// console.log('hehe: ');
// console.log(new VRPSolution($V($V(ar))));
// ar.forEach(function (a) {
// console.log(self.problem.demand(a));
// });
neighbors.push(new VRPSolution($V($V(ar))));
//}
}
}
}
}
}
//console.log('-neighbors-');
//console.log(neighbors);
var unique_neighbors = [];
neighbors.forEach(function (neighbor) {
var duplicate = unique_neighbors.some(function (elem) {
return neighbor.identical(elem);
});
duplicate = duplicate || candidate.identical(neighbor);
//console.log(duplicate);
if (!duplicate) {
neighbor.fitness = self.problem.fitness(neighbor); //make sure we evaluate the neighbor before returning
//console.log('neighbor fitness: ' + neighbor.fitness);
unique_neighbors.push(neighbor);
}
});
//console.log('unique_neighbors');
//console.log(unique_neighbors);
assert(unique_neighbors.length > 0, "unique neighborhood set is empty!");
return unique_neighbors;
}
function neighbor (candidate) {
assert(this.problem.valid(candidate));
var N = this.problem.dimension(); //number of city nodes
var E = N; //number of travel paths
var origin = candidate.data.elements.slice(0);
}
var VRP_TS = defineClass({
name: 'VRP_TS',
extend: TS,
methods: {
'neighbors': neighbors,
'neighbor' : neighbor
}
});
module.exports.VRP_TS = VRP_TS;